#!/usr/local/bin/perl
#################################################################################
# COPYRIGHT NOTICE																#
# Copyright (c) 1998-2007 Ira L. Gershenhorn.  All Rights Reserved.				#
#																				#
# mgFargo may be used and modified free of charge by anyone so long as			#
# this copyright notice and the comments above remain intact.  By using this	#
# code you agree to indemnify Ira L. Gershenhorn from any liability that		#  
# might arise from it's use.													#  
#																				#
# Selling the code for this program without prior written consent is			#
# expressly forbidden.  In other words, please ask first before you try and		#
# make money off of my program.													#
#																				#
# Obtain permission before redistributing this software over the Internet or	#
# in any other medium.	In all cases copyright and header must remain intact.	#
#																				# 
# mgFargo is free software; you can redistribute it and/or modify it			#
# under the terms of the GNU General Public License as published by the			#
# Free Software Foundation; either version 2 of the License, or (at				#
# your option) any later version.												#
#																				#
# mgFargo is distributed in the hope that it will be useful, but				#
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY	#
# or FITNESS FOR A PARTICULAR PURPOSE.&nbsp; See the GNU General Public			#
# License for more details.														#
#									     										#
# You should have received a copy of the GNU General Public License				#
# along with this program; if not, write to the Free Software					#
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.	#
#################################################################################
# Debug Commands
# perl mgCvt9to8.pl ??

=head1 NAME

B<mgCvt9to8.pl> - Convert a Magic 9.4 export so it looks like a Magic 8.3 export

=head1 SYNOPSIS

C<mgCvt9to8>
Copy your magic 9 export to m9a.exp and it will output to m8a.exp 
%perlpath%bin\perl  \\solo\e\dev\mgFargo\mgFargo-802.pl -i \\solo\e\dev\mgFargo\mgFargo.ini nsa

For Detailed Help type: mgCvt9to8 -h

=head1 ARGUMENTS

=head1 EXAMPLES


=head1 BUGS

=head2 Planned Enhancements

=head1 SUPPORT

Ira Gershenhorn E<lt>ira@gershenhorn.comE<gt>

=head1 HISTORY
 2009-0721 Double all until cnt expressions, because there was much truncation in the Hiscox output
 2006-1203 Created

=head1 AUTHOR

Ira Gershenhorn E<lt>iragershenhorn@mindspring.comE<gt>

=cut

#http://www.rexswain.com/perl5.html#string  a very nice resource
   
#no sequence numbers #0604
#Version/Revision history
#2007-12-18  10b3a  from 10b3. created after 10b4 but 10b4 should have these updates.  So Raise_event shows condition and flow and args.
#
#use warnings;
#use strict;
use Getopt::Std;
use XML::LibXML; #is much much faster than XML::Simple and supports XPath syntax
use XML::XPath;
use Data::Dumper;
#use Devel::DumpStack;
# LibXML and XPath are not part of the default distribution so must be
# added.  Here I ran ppm from c:\perl\bin path and installed them.
# Note that this will ONLY work with v5.10.1 . I have tried it with v5.12 and those modules did not exist in ppm (perl package manager)
# The perl distribution on vpc11202 was copied from hxe30381 after installing ActiveState Perl v5.12
#C:\Perl\bin>ppm install XML::XPath
#  39 files installed
#C:\Perl\bin>ppm install XML::LibXML
# 110 files installed
#C:\Perl\bin>ppm install Data::Dumper
#No missing packages to install
# batch file
#set path=%PATH%;c:\perl\site\bin;c:\perl\bin
#c:\perl\bin\perl e:\develop\ezr\mgFargo-101-00u01.pl  -f "e:\develop\gersheni\UW_24Feb_RMConverted\Source" -s "e:\unipaas\unipaas_1.9\support" -b 2481 -e 2481

my %opt=();
getopts("b:e:vhf:i:s:",\%opt) or basicUsage();

# general hash for expanding single letter terms.
my %gExpand1    = ("O"=>"Online",
				   "B"=>"Batch",
				   "Q"=>"Query",
				   "M"=>"Modify",
				   "D"=>"Delete",
				   "C"=>"Create",
				   "R"=>"Range",
				   "L"=>"Locate",
				   "Y"=>"Yes",
				   "N"=>"No");
my %gExpand2    = ("Y"=>"Yes",
				   "N"=>"No",
				   "A"=>"Ascending",
				   "D"=>"No",
				   "O"=>"Online",
				   "B"=>"Batch");

my %taskType    = ("O"=>"Online",
				   "B"=>"Batch");
my %initialMode = ("Q"=>"Query",
				   "M"=>"Modify",
				   "D"=>"Delete",
				   "C"=>"Create",
				   "R"=>"Range",
				   "L"=>"Locate");
my %yesno       = ("Y"=>"Yes",
				   "N"=>"No");
my %ascDesc     = ("A"=>"Ascending",
				   "D"=>"Descending",
				   "N"=>"Not Applicable" );
my %optype      = ("P"=>"Prog",
				   "T"=>"Task",
				   "U"=>"UDP",
				   "C"=>"COM",
				   "R"=>"Remote",
				   "E"=>"Expression");

my %engDir		= ("I"=>"Directive:Ignore",
				   "S"=>"Directive:As strategy",
				   "R"=>"Directive:Auto retry",
				   "U"=>"Directive:User Retry",
				   "B"=>"Directive:Rollback and Retry",
				   "A"=>"Directive:Abort Task");
my %errorList	= ("0"=>"Any",
				   "1"=>"Locked Row",
				   "2"=>"Duplicate Index",
				   "3"=>"Constraint Failure",
				   "4"=>"Trigger Failure",
				   "5"=>"Record has been updated",
				   "6"=>"Record changed by another user",
				   "8"=>"Insert/Update/Delete failure",
				   "9"=>"Unmapped Errors");

my %attr		= ("A"=>"Alpha",
				   "N"=>"Numeric",
				   "B"=>"Logical",
				   "D"=>"Date",
				   "T"=>"Time",
				   "M"=>"Memo",
				   "I"=>"Image");
my %editControl = ("S"=>"Static",
				   "E"=>"Field",
				   "P"=>"Pushbutton",
				   "T"=>"Table",
				   "C"=>"CheckBox",
				   "L"=>"Slider",
				   "O"=>"OLE2",
				   "I"=>"Image",
				   "H"=>"RichEdit",
				   "M"=>"HTMLFile",
				   "N"=>"Line",
				   "X"=>"ActiveX",
				   "R"=>"Radio",
				   );
my %mod			= ("R"=>"Read",
				   "W"=>"Write",
				   "A"=>"Append",
				   "D"=>"Direct");
my %lnkmod		= ("R"=>"Query   ",
				   "W"=>"Write   ",
				   "N"=>"Validate",
				   "A"=>"Create  ");
my %stpmod		= ("E"=>"Error",
				   "W"=>"Warning",
				   "V"=>"Warning");
my %read		= ("N"=>"Normal",
				   "F"=>"Fast",
				   "D"=>"Damaged",
				   "R"=>"Reindex");
my %opn			= ("R"=>"Read",
				   "W"=>"Write",
				   "N"=>"None");
my %ioformat	= ("P"=>"Page",
				   "L"=>"Line",
				   "N"=>"None");
my %iomedia		= ("P"=>"Printer",
				   "C"=>"Console",
				   "S"=>"Standard",
				   "I"=>"Internal",
				   "U"=>"User");
my %eventscope	= ("S"=>"Scope:Subtree",
				   "T"=>"Scope:Task");
my %eventcall	= ("P"=>"Program",
				   "T"=>"Task");
my %evttype		= ("I"=>"Internal",
				   "U"=>"User",
				   "S"=>"System",
				   "R"=>"Error",
				   "N"=>"None" );

my %brkcontext	= ("R"=>"Record",
				   "T"=>"Task",
				   "H"=>"Handler",
				   "C"=>"Control",
				   "G"=>"Group");
my %brktype		= ("S"=>"Suffix",
				   "P"=>"Prefix",
				   "M"=>"Main",
				   "U"=>"User",
				   "C"=>"Change",
				   "V"=>"Verification");
my %blocktype	= ("I"=>"If",
				   "E"=>"Else",
				   "L"=>"Loop" );

my %realvirt	= ("R"=>"Real",
				   "V"=>"Virt" );
my %argtype		= ("8"=>"as OUTPUT",
				   "10"=>"as INPUT" );
my %invopt		= ("M"=>"Call Method",
				   "S"=>"Set Property" );

my %formio_op	= ("O"=>"Output",
				   "I"=>"Input" );

my %evalEnd= ("B"=>"Before entering record",
			  "A"=>"After updating record",
			  "I"=>"Immediately when condition is changed" );
my %lstrg  = ("O"=>"On Modify",
			  "B"=>"Before Update",
			  "N"=>"No Lock",
			  "M"=>"M",
			  "I"=>"Immediate" );#Locking strategy may have no meaning in UniPaaS
my %sloc   = ("M"=>"M",
			  "I"=>"I" );#Strategy On Locked Record may have no meaning in UniPaaS
my %sfail  = ("R"=>"Recover",
			  "A"=>"Abort" );#Error Behaviour Strategy / Failed Record Access may have no meaning in UniPaaS
my %cstrat = ("P"=>"Position",
			  "D"=>"Position and Data",
			  "N"=>"None",
			  "T"=>"As Main Table" );#Failed Record Access may have no meaning in UniPaaS

my %tmode  = ("P"=>"Physical",
			  "D"=>"Deferred",
			  "W"=>"Within active transaction",
			  "N"=>"Nested deferred" );#Failed Record Access may have no meaning in UniPaaS
my %tbegin = ("N"=>"None",
			  "B"=>"Before task prefix",
			  "P"=>"Before record prefix",
			  "S"=>"Before record suffix",
			  "U"=>"Before record update",
			  "O"=>"On record lock" );#Failed Record Access may have no meaning in UniPaaS

my %eTypeStr = ("S"=>"System",
				"N"=>"None",
				"T"=>"Timer",
				"E"=>"Expression",
				"I"=>"Internal" );
my %eForceExit=("C"=>"Control",
				"N"=>"None",
				"E"=>"Editing",
				"R"=>"Pre Record update",
				"P"=>"Post Record update" );
#end of General Hashs

my $p_data;
my $debugEE = 0;
my $ppCnt = 0;
my $mgMajorVers = 0;
my $mgMinorVers = 803;
my $versionDate = "2007-12-18";
my $copyrightLine = "mgFargo V$mgMajorVers.$mgMinorVers Copyright (c) 1998-2007 Ira L. Gershenhorn & Co., Inc.";
my $generatingVB = 0;

my $currentDb;
my @dbObjs;
my $HierLevelT;
my $beginProg = 2;
my $endProg = 9999;
if ($opt{h}){  detailedUsage(); }
if ($opt{m}){  manpage(); }
#the following uses are only here for Perl2exe.  It doesn't know dependencies.
if( $opt{x} ) {
	use IO;
	use IO::Seekable;
	use IO::File;
	use IO::Handle;
	use Pod::Usage;
	use Pod::Parser;
}

#if( ! -f $ARGV[0] ){ $error = "main input file \"$ARGV[0]\" does not exist"; usage();}

#Getopt::Long::Configure('bundling');
#GetOptions('verbose|v' => \$verbose,
#		  'trace' => \$trace,
#		  'help|?|h' => \$help,
#		  'manual' =>  \$manual,
#		   'debug' => \$debug,
#		   'numberfiles|n' => \$numberfiles,
#		   'programdict|p' => \$programdict,
#		   'filedict|d' => \$filedict,
#		   'uniquify|u' => \$uniquify,
#		   'start|s' => \$start,
#		   'end|e' => \$end)
#  or pod2usage(2);


	$| = 1;  #flush STDOUT.  otherwise no output for a long time.
   my $os = $ENV{OS};
   $context = '';
   $brktyp = '';
	$useDfNamePrefixes = 1;
	my $ddPrefixSeparator = '.';

	$flowMode{S} = 'Step';
	$flowMode{s} = '!step!';
	$flowMode{F} = 'Fast';
	$flowMode{C} = 'Combined';
	$flowMode{B} = 'on Zoom (Before)';
	$flowMode{Z} = 'on Zoom (Before)';#version 8
	$flowMode{A} = 'on Zoom (After)';
	$flowMode{J} = 'on Zoom (After)';#version 8
	$flowMode{j} = '!on zoom (after)!';#version 8
	$flowMode{Z} = '!on zoom (???)!';#version 9 line 117832
	$flowDir{F} = 'forward';
	$flowDir{C} = 'forward,back';
	$flowDir{B} = 'backwards';

	$initialTaskMode{M} ='Modify';#verified
	$initialTaskMode{C} ='Create';#verified
	$initialTaskMode{D} ='Delete'; #verified
	$initialTaskMode{E} ='Query';#verified
	$initialTaskMode{P} ='As Parent';#verified
	$initialTaskMode{L} ='Locate';
	$initialTaskMode{R} ='Range';
	$initialTaskMode{K} ='Key';
	$initialTaskMode{S} ='Sort';
	$initialTaskMode{O} ='Files'; #verified
	#$initialTaskMode{N} ='Options';#verified

	#tab string

	#$tabstr = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
	$tabstr = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; #cut back to keep from running amok.
	$spacestr = "                                                                                                                                               ";
	my $start1 = time;
	my $start2;
	my $cnt = 0;
	my $hasApps = "N";
	my $hasModels = "N";
	my $hasTables = "N";
	my $hasPrgs = "N";
	my $hasHelps = "N";
	my $hasRights = "N";
	my $hasMenus = "N";
	my $hasComp = "N";
	my $hasAppProp = "N";
	my $hasWModels = "N";
	my $hasISN = "N";

	my $rights = 0;
	my $p = 0;#program index
	my $t = 0;#task index
	my $e = 0;#expression index
	my $lineNumber = 0;

	#Version 10 differs from 9 and others in that we don't work with an export file but with the source folder.
	my $sourcePath;   #sourcePath may replace appExportFile.
	
	#my $appExportFile;  #this is the import file - either application or a single export.
	$beginProg  = $opt{b};
	$endProg  = $opt{e};
	$sourcePath = $opt{f};
	
	$supportFilesPath = $opt{s};
	if( $supportFilesPath ne ''){$supportFilesPath .= '\\';} # add a backslash
	$mgFargoIniPath = $opt{i};
	if( $mgFargoIniPath ne ''){$mgFargoIniPath .= '\\';}
	# is there a version 10 corollary for the Act.eng and fnt.eng files?
	read_act_eng10();#587
	read_fnt_eng();#600
	read_mgFargo_ini();
#	exit();
#
#	#override command line options with mgFargo.ini #588
#	if (defined ($ini{lc(Verbose)           })){ $opt_v = $ini{lc(Verbose)};  }
#	if (defined ($ini{lc(numberFiles)       })){ $opt_n = $ini{lc(numberFiles)};}
#	if (defined ($ini{lc(uniquifyVars)      })) { $opt_u = $ini{lc(uniquifyVars)};}
#
#	if (defined ($ini{lc(useDfNamePrefixes) })){ $opt_f = $ini{lc(useDfNamePrefixes)};}
#
#	if (defined ($ini{lc(startProgram)      })){ $opt_s = $ini{lc(startProgram)}; }
#	if (defined ($ini{lc(endProgram )       })){ $opt_e = $ini{lc(endProgram)}; }
#	if (defined ($ini{lc(progList)          })){ $opt_p = $ini{lc(progList)}; chomp($opt_p)}
#	if (defined ($ini{lc(internalFileExport)})){ $opt_d = $ini{lc(internalFileExport)}; chomp($opt_d) }
#
#	my $rowColumnFirst   = $ini{lc(rowColumnFirst     )}; #600 doesn't necessarily need to be in mgFargo.ini - will not crash if its missing.
#	my $showScaledToFit  = $ini{lc(showScaledToFit    )};
#	my $showScaledToFill = $ini{lc(showScaledToFill   )};
#	my $showAllowCrInData= $ini{lc(showAllowCrInData  )};
#
#	my $useDfNamePrefixes = defined($opt_f)?$opt_f:0;#default is not to prepend #574
#	my $uniquifyVars = defined($opt_u)?$opt_u:1; #default is to uniquify #574

#	my @dd = ();
	my $uniquifyVars = 1;#was once an option.
	$p = 0;
	print STDOUT "...first pass. loading variables and expressions, Begin: $beginProg, End: $endProg \n";
	$pass = 1;
	load();
	print STDERR "Total Run times (secs), pass1:", $start2 - $start1 . ' pass2:', time - $start2 ;
	# exit here


	# Perl trim function to remove whitespace from the start and end of the string
	sub trim($)
	{
		my $string = shift;
		$string =~ s/^\s+//;
		$string =~ s/\s+$//;
		return $string;
	}
	sub formName ($$){
		my ($taskp, $index) = @_;
		my ($fp);
		return($form[$index]->{name} = $formName);
		
		$index++;
		print STDOUT "formName index: $index pt Nodename:" . $taskp->nodeName . " p_data:" . $p_data->nodeName . "\n";
#	First 'enhancement as result of profiling - may not be an improvement.  didn't hurt though.		
#		@fp = $p_data->findnodes("//Application/ProgramsRepository/Programs/Task");
		$firstTask = $p_data->find("//Application/ProgramsRepository/Programs/Task");
#		@fxp = $fp[0]->findnodes("TaskForms/FormEntry"); #
#	Second enhancment
		$taskForm = $firstTask->find("TaskForms"); 
		@taskFormChildren = $firstTask->childNodes; 
		foreach $taskFormChild (@taskFormChildren){
			$id = $taskFormChild->getAttribute( "id");
			if( $index eq $id ){
				$name = getAttributeOfNode($taskFormChild,"PropertyList/FormName", "valUnicode", 0);
				return( $name );
			}
		}
# 		@fxp = $firstTask->findnodes("TaskForms/FormEntry"); 
#		foreach $fp (@fxp){
#			print STDOUT "formName " . $fp->nodeName . "\n";
#			$id = $fp->getAttribute( "id");
#			if( $index eq $id ){
#				$name = getAttributeOfNode($fp,"PropertyList/FormName", "valUnicode", 1);
#				return( $name );
#			}
#		}

		return ("not found");
	}
	sub taskName ($$){
		my ($taskp, $index) = @_;
		foreach $hp ($taskp->findnodes("Task/Header")){
			$ISN_2 = $hp->getAttribute( "ISN_2");
			if( $index == $ISN_2 ){
				$name = $hp->getAttribute( "Description");
				return( $name );
			}
		}
		return ("not found");
	}
	sub load{
	   loadHeader();
	   print STDOUT "Load Project Properties, Models, Folders, Helps, Menus, Componentns, Rights, Data Source Index\n";
	   $projectProperties_xml = XML::LibXML->new(); 
	   $pp_data = $projectProperties_xml->parse_file ("$sourcePath\\ProjProps.xml");## XML:LibXML::Parser	This is 1.65, if 1.70 could use load_xml
#	   print Dumper($pp_data);## not a useful result with LibXML, only good with XML::Simple

	   $models_xml = XML::LibXML->new();
	   $m_data = $models_xml->parse_file ("$sourcePath\\Models.xml");
	   print STDOUT "loading Models\n";
	   foreach $model ($m_data->findnodes('//Application/ModelsRepository/Models/Object')){
		   parseModel($model);
	   }

	   $folders_xml = XML::LibXML->new();
	   $folders_data = $folders_xml->parse_file ("$sourcePath\\Progs.xml");

	   $helps_xml = XML::LibXML->new();
	   $h_data = $helps_xml->parse_file ("$sourcePath\\Helps.xml");

	   $menus_xml = XML::LibXML->new();
	   $mnu_data = $menus_xml->parse_file ("$sourcePath\\Menus.xml");

	   $comps_xml = XML::LibXML->new();
	   $cmp_data = $comps_xml->parse_file ("$sourcePath\\Comps.xml");

	   $rights_xml = XML::LibXML->new();
	   $r_data = $rights_xml->parse_file ("$sourcePath\\Rights.xml");

	   $dataSourcesIndex_xml = XML::LibXML->new();
	   $dsi_data = $dataSourcesIndex_xml->parse_file ("$sourcePath\\DataSourcesIndex.xml");

	   print STDOUT "Load Data Sources\n";
	   $dataSources_xml = XML::LibXML->new();
	   $ds_data = $dataSources_xml->parse_file ("$sourcePath\\DataSources.xml");
	   foreach $dobj ($ds_data->findnodes ( "//Application/DataSourceRepository/DataObjects/DataObject" )){
		   $ddfile = $dobj->getAttribute("id");
		   $dd[$ddfile]{folder}= $dobj->getAttribute("Folder");
		   $dd[$ddfile]{name}= $dobj->getAttribute("name");
		   $dd[$ddfile]{desc}= $dobj->getAttribute("name");
		   $dd[$ddfile]{dbname}= $dobj->getAttribute("PhysicalName");
		   $dd[$ddfile]{dsource}= $dobj->getAttribute("data_source");
		   $dd[$ddfile]{folder}= $dobj->getAttribute("Folder");
		   $dd[$ddfile]{key}->[0]= 'None';
		   $ddfield=0;
		   foreach $dfield ($dobj->findnodes ( "Columns/Column" )){
			   $dd[$ddfile]{field}->[$dfield->getAttribute("id")]= $dfield->getAttribute("name");
		   }
	   }
	   print STDOUT "Load Program Headers\n"; # This file is not reliable - it doesn't contain all entries. == Actually once you exit Magic Studio, it will
	   $ProgramHeaders_xml = XML::LibXML->new();
	   $ph_data = $ProgramHeaders_xml->parse_file ("$sourcePath\\ProgramHeaders.xml");
	   $i=0;
	   foreach $php ($ph_data->findnodes( "//Application/ProgramsRepositoryHeaders/Program/Header")){
		   $i++;
		   $index = $php->getAttribute("id");
		   $ph[$index]->{desc} = $php->getAttribute("Description");
		   $ph[$index]->{i} = $i;
	   }
	   readPrograms();
	   print STDOUT "End\n";
   	   exit();

#	   print STDOUT Dumper($data);
#	   loadRights() ;
	   $lineNumber = 0;
   }
   sub dataSourceIndexName($$){
	   ($dataSourceNum, $indexNum ) = @_;
	   return( getAttributeOfNode($ds_data, "//Application/DataSourceRepository/DataObjects/DataObject[$dataSourceNum]/Indexes/Index[$indexNum]", "name" , 0));
   }
   sub dataSourceFieldName($$$){
	   my ($dataSourceNum, $fieldNum, $debug ) = @_;
	   my ($dsfield);
	   my $otherFieldName = $dd[$dataSourceNum]{field}->[$fieldNum];
#	   $dsfield = getAttributeOfNode($ds_data, "//Application/DataSourceRepository/DataObjects/DataObject[$dataSourceNum]/Columns/Column[$fieldNum]", "name" , 0);
#	   if( $debug ){
#		   print STDOUT "ds/field: $dataSourceNum, $fieldNum $dsfield\n";
#	   }
	   return( $otherFieldName );
   }
   sub dataSourceName ($){
	   ($ds_index) = @_;
	   if( $ds_index eq 0 || $ds_index eq '' ){
		   return ('','','','');
	   }
	   else {# Second enhancement big change - for 570 from 35 to 7 seconds.
		   my $do_magicName = $dd[$ds_index]{name};
		   my $do_physName = $dd[$ds_index]{dbname};
		   my $do_folder = $dd[$ds_index]{folder};
		   my $do_dataSource = $dd[$ds_index]{dsource};

#		   my @do_nodes = $dsi_data->findnodes("//Application/DataSourceRepository/DataObjects/DataObject[$ds_index]");
#		   #This findnodes fails if the xml version is not in the xml file. ie. poorly formed xml.
#		   $nodeCount = @do_nodes;
#		   print STDOUT "dataSourceName: Index:$ds_index Node count: ".@do_nodes." \n";
#		   printNodeNames(@do_nodes, 0);
#		   my $do_magicName = @do_nodes[0]->getAttribute("name");
#		   my $do_physName = @do_nodes[0]->getAttribute("PhysicalName");
#		   my $do_folder = @do_nodes[0]->getAttribute("Folder");
#		   my $do_dataSource = @do_nodes[0]->getAttribute("data_source");
#		   print STDOUT "dataSourceName: Magic name: $do_magicName \n";
		   return( $do_magicName, $do_folder, $do_dataSource, $do_physName );
	   }
   }
   sub whichFolder ($) {# pass the id of the program and return the
# foldername
	   ($progID) = @_;
	   $folderName = '___';
	   foreach $folder ($folders_data->findnodes("//Application/Header/Folders/Folder"))  {
		   foreach $folderChild ($folder->childNodes){
			   if($folderChild->nodeName eq 'Name'){
				   $folderName = $folderChild->getAttribute( 'val' );
			   }
			   elsif ($folderChild->nodeName eq 'StartsAt'){
				   $startsAt = $folderChild->getAttribute( 'val');
			   }
			   elsif ($folderChild->nodeName eq 'NumberOfEntries'){
				   $numberOfEntries = $folderChild->getAttribute( 'val');
			   }
		   }
#		   print STDOUT "FolderName:$folderName Starts:$startsAt Has: $numberOfEntries Entries $progID\n";
		   if( $progID >= $startsAt && $progID <= $startsAt + $numberOfEntries -1 ){
			   return($folderName);
		   }
		   else{
			   $folderName = '___';
		   }
	   }
	   return($folderName);
   }
   sub readPrograms{
	   $prg1Xml = XML::LibXML->new();
	   $prgXml = XML::LibXML->new();
	   foreach $ph_prg ($ph_data->findnodes('//Application/ProgramsRepositoryHeaders/Program'))
	   {
		   foreach $ph_prgchild ($ph_prg->childNodes){
			   if($ph_prgchild->nodeName eq 'Header'){
				   $PrgId = $ph_prgchild->getAttribute('id');
				   $ph_prgFile = "Prg_" . $PrgId .".xml";
				   if( $PrgId == 1){#would be better to look at the Mainfile tag
					   $p1 = $prg1Xml->parse_file ("$sourcePath\\$ph_prgFile");
				   }
				   if( $PrgId > $endProg){ ##00u01 changed the elseif to if so prg 1 would show
#					   exit();
				   }
				   elsif( $PrgId == 1 || $PrgId >= $beginProg){
					   $progName = $ph_prgchild->getAttribute('Description');
					   $progPublic = '___';
					   foreach $headerchild ($ph_prgchild->childNodes){
						   if( $headerchild->nodeName eq 'Public'){
							   $progPublic = $headerchild->getAttribute('val');
						   }
						   if( $headerchild->nodeName eq 'Comment'){
							   $taskComment = $headerchild->getAttribute('val');
						   }
						   if( $headerchild->nodeName eq 'Resident'){
							   $isResident = $headerchild->getAttribute('val');
						   }
					   }
					   $p_data = $prgXml->parse_file ("$sourcePath\\$ph_prgFile");
					   @pt = $p_data->findnodes('//Application/ProgramsRepository/Programs/Task');## there should only be one- the main task of a program
					   $progFolder = whichFolder ($PrgId);
					   print STDOUT "$PrgId\t$ph_prgFile\t$progName\t$progFolder\t$progPublic\n";
					   writeProgram();
				   }
			   }
		   }
	   }
   }
   sub loadHeader{
	   print STDOUT "Loading Header...\n";
	   do {
		   $hasApps = 'Y';
		   $hasModels = 'Y';
		   $hasTables = 'Y';
		   $hasPrgs = 'Y';
		   $hasHelps = 'Y';
		   $hasRights = 'Y';
		   $hasMenus = 'Y';
		   $hasComp = 'Y';
		   $hasAppProp = 'Y';
		   $hasWModels = 'Y';
		   $hasISN = 'Y';
	   } 
   }
	sub parseModel($){ 
		my ($object) = @_;

		$modeln = $object->getAttribute ('id');
		$models[$modeln]->{name} = $object->getAttribute ('name');
		$models[$modeln]->{class} = getAttributeOfNode($object,"PropertyList", "model", 0);
		$models[$modeln]->{desc}= $desc = getAttributeOfNode($object,"PropertyList/Model", "attr_obj", 0);
		$models[$modeln]->{range} = getAttributeOfNode($object,"PropertyList/Range", "valUnicode", 0);
		$models[$modeln]->{pic}= getAttributeOfNode($object,"PropertyList/Picture", "valUnicode", 0);
		$models[$modeln]->{itemlist}= getAttributeOfNode($object,"PropertyList/GuiDisplayTable/PropertyList/ItemsList", "valUnicode", 0);
		#($comment) = $_ =~  /COMMENT="([^"]+)"/;#I don't do anything with this.
		#$comment =~ s//\n/g;#replace backspaces with new lines

		if ( $desc =~ /FIELD_(.+)/) {
			$models[$modeln]->{attr}= ucfirst(lc($1)); #Capitalization or Initial Caps
		}
		#should dump them to separate file with usage count. :-)
		# and list of unused models.
	}
	sub parseDataSourceIndexLine{
		if ( /<DataObject /){ #the space is very important. distinguishes it from DataObjects
			$modeln = $_ =~  /id="(.+)"/;
			$models[$modeln]->{desc}=$_ =~ /name="(.+)"/;
			($comment) = $_ =~  /COMMENT="([^"]+)"/;#I don't do anything with this.
			$comment =~ s//\n/g;#replace backspaces with new lines
		}
		elsif ( /<PropertyList attr_obj="FIELD_(.+)"/) {
			$models[$modeln]->{attr}= ucfirst(lc($1)); #Capitalization or Initial Caps
		}
		elsif ( /<Picture /) {
			$models[$modeln]->{pic}= $1 if /valUnicode="(.+)"/;
		}
		elsif ( /<ItemsList /) {
			$models[$modeln]->{itemslist}= $1 if /valUnicode="(.+)"/;
		}
		elsif ( /<Range /) {
			$models[$modeln]->{range}= $1 if /valUnicode="(.+)"/;
		}
		#should dump them to separate file with usage count. :-)
		# and list of unused models.
	}
	# THe function IN is a problem.  Most functions have more than two chars.  This one doesn't and I don't want to treat as a var.
	# eg.  EXP="CndRange (NOT (IN (IF,'','  1','  2','  3')),IF)",
	# must look ahead for paren.  Should be same issue as IF detection.
	# Want to expand instances of ExpCalc ('nnn'EXP).  Up til now passed as is. version:940-10b3a1
	#
	# In Version 10, letters are no longer used. Rather some brace notation is used.
	#
	#  Reference syntax:
	#  {32768, 1 } = first field in Main task
	#  {0, 1 } = first select field in current task
	#  {1, 1 } = first select field in parent task
	#  {2, 1 } = first select field in parent of parent task
	sub varName ($){
		my ($refString) = @_; #format {x,y}
		my ($level, $varIndex) = $refString =~ /{(\d+),(\d+)}/;
		if( $level == 32768 ){
			$varName = getAttributeOfNode ( $p1, "//Application/ProgramsRepository/Programs/Task/Resource/Columns/Column[$varIndex]",'name', 0);
		}
		else{
			$varName = $fields[$HierLevelT-$level][$varIndex]->{name};
#			print STDOUT "varName fields $HierLevelT $level $varIndex = $varName  \n" if $refString eq "{3,22}" ;
		}
#		print STDOUT "refString: $refString Level:$level, Var:$varIndex HT:$HierLevelT Varname: $varName\n" if $varIndex == 77;
		return $varName;
	}
	sub expandedExpression($){
		my ($in) = @_;
		my $lastToken = 'none';
		my $result = '';

		if( $ppCnt > 0 ){
			print STDOUT "expandedExp:$cnt:$lineNumber: $in\n";
		}

		while ($in =~ m'
				 (
				 \'\'           | # null string
				 \'[^\']*?\'    | # strings
				 IN\s\( |	#IN detection should be same as IF detection
				 IF\s\( |
				 \sOR\s |
				 \sAND\s |
				  <> |
				  <= |
				  >= |
				 [&<>\.\-+*,=\(\)\/] | # punctuation - adding space just spaces out the output - not useful
				 {\d+,\d+}    |#10 Symbols
				 [A-Za-z]+         | # symbols pre 10
				 [0-9.]+           #572 attempt to fix problem of spaced out decimal in 0.02 construct
				 )
			   'xg){
			$token = $1;
			if( $debugEE ){print STDOUT "Token: $token LT:$lastToken ";}
			if ( $token =~/IF\s\(/){
				if( $debugEE ){print STDOUT "1 \n";}
				$lastToken = 'if';					$result .= $token . ' ';
			}
			elsif ( $token =~/IN\s\(/){
				if( $debugEE ){print STDOUT "2 \n";}
				$lastToken = 'in';					$result .= $token . ' ';
			}
			elsif ( $token =~/\s(OR|AND)\s/){
				if( $debugEE ){print STDOUT "3 \n";}
				$lastToken = 'and-or';			    $result .= $token;
			}
			elsif ( $token =~/\'[^\']*?\'/){
				if( $debugEE ){print STDOUT "4 \n";}
				$lastToken = 'string';				$result .= $token;
			}
			elsif ($token =~ /^[&<>+*,=\'\(\)\/]/){ #force match at beginning of line
				if( $debugEE ){print STDOUT "5 \n";}
				if (($lastToken eq 'string') && ($token eq '&')) {
					$result .= ' ';
				}
				$lastToken = 'punct';
				if( $token eq '=' ){
					$result .= '==' . ' '; #573 use equivalence. There are never assignments within expressions.
				}
				else {
					$result .= $token . ' ';
				}
			}
			else{
				if( $debugEE ){print STDOUT "6 \n";}
				if ($lastToken eq 'string'){
					$lastToken = 'const';		$result .= $token;
				}
				else{
					if ( $token =~ /{\d+,\d+}/){
						$lastToken = 'var';		$result .= varName($token) . ' ';
						if($debugEE){print STDOUT " [EE:$token,$lastToken,$result] \n";}
					}
					else{
						$lastToken = 'keyword';	$result .= $token . ' ';
					}
				}
			}
		}
		$result =~ s/\'({\d+,\d+})\'VAR/'@' . varName($1)/ge; 	#0586 replace any instances of "'xx'VAR" with "@variable".
		$result;
	}
	sub nextTask($$){
		# called only from readTaskHierarchy
		my ($taskp, $dots )=@_;
		my $taskName = getAttributeOfNode($taskp,"Header","Description", 0);
		$dots .= '.1';
		$dotcnt = $dots =~ tr/\./\./;#count em		

		print  substr( $tabstr, 0, $dotcnt);
		print "$taskName\t$dots\n";
		foreach $child ( $taskp->childNodes){
			if( $child->nodeName eq 'Task'){
				nextTask($child, $dots);
				$dots =~ s/(\d+)$/$1+1/e;  #Try the next one
			}
		}
	}
	sub readTaskHierarchy($){
		# called only from getPrgResources10
		my ($taskp) = @_;
		my $taskName = getAttributeOfNode($taskp,"Header","Description", 0);
		print "\nTask Hierarchy:";
		print "\n------------------------------------------------------------\n";
		nextTask($taskp,'');
		print "\n------------------------------------------------------------\n";
	}
	sub initTaskVarsPrescan{#for prescan
		$formNumber=0;
		$vr=0;  #virtual-real index
		$e=1;
		$j=1;
		$v=0;#these are pre-inited. They really do begin at 1. see ^FIELD
		$maindbf=0;
	}
	sub setPropListType{
		if ( $prevSeg eq 'DSP' ){ $propListType = 'DSP'; }
		elsif ( $prevSeg eq 'ITM' ){ $propListType = 'ITM'; }
		elsif ( $prevSeg eq 'FLD' ){ $propListType = 'FLD'; }
		else  {
			$propListType = 'OTH';
#			print STDOUT "  --parseprog: PROPLIST: $lineNumber $propListType prevSeg:[$prevSeg] \n\tTHIS:$_";
#			exit();
		}
		$prevSeg = '';
	}
	sub nextVar
	{
		$currentVar++;
		my $highChar = $currentVar/26;
		my $lowChar = $currentVar % 26;

		my $highCharA = ($highChar==0)?'':chr($highChar+65);
		my $lowCharA = chr($lowChar+65);
		$currentVarA = $highCharA . $lowCharA;
	}
	sub tabOut{
		#why distinguish $indentUsed from $indentLevel?
#		print substr $tabstr, 0, $indentUsed;
		if( $indentLevel+$indentOnce > 1 ) {
#			print "$indentLevel", substr $tabstr, 0, $indentLevel;
#			print "($indentLevel)";
			print substr $tabstr, 0, $indentLevel-1 + $indentOnce;
		}
		$indentOnce = 0;
	}
	#hopefully this is not the FLW in the task descriptor eg. FLW=B,DEL=N,END=N,EMOD=ABI,   online/batch,  never,always(Y), expr ends, ends after, before,immediate. (end=Y, = yes it ends)
	#no this is the standard FLW={CND=Y,MOD=B,DIR=C}} on the end of most expressions.
	# while MOD and DIR is irrelevant in all but MAIN, CND is always relevent.
	#  Some elses are not picked up as such - it seems a plain Else will be printed  as an else , yet an else with a condition will not.
	# BLOCK={END_BLK=426,MOD=E,END=702,FLW={CND=336,MOD=B,DIR=C}},
	# BLOCK={END_BLK=702,MOD=E,END=702,FLW={CND=Y,MOD=B,DIR=C}},
	# tool for testing
	# F:\Perl\site\bin>xpath "f:\Program Files\MSe\uniPaaS 1.8\Projects\Hiscox Dev From 9\Source\DataSources.xml"  "//Application"
	#xpath "f:\Program Files\MSe\uniPaaS 1.8\Projects\Hiscox Dev From 9\Source\DataSourcesIndex.xml"  "//Application/DataSourceRepository/DataObjects/DataObject[320]"
	sub getValExpOfNode ($$){
		my $attr = '';
		($node, $xpath) = @_;
		@nodes = $node->findnodes ($xpath);
		if (@nodes > 0){
			$attr = @nodes[0]->getAttribute("val");
			$attr = $yesno{$attr}; # expand
			if( $attr eq '' ){
				$attr = @nodes[0]->getAttribute("exp");
				$expression = getAttributeOfNode( $node, "Expressions/Expression/[".$attr ."]", "val", 0);
			}
		}
		else {return ('')};
	}
	#third improvement.  not really any better 7-8 seconds but its much cleaner.
	sub getAttributeOfNode ($$$$){
		my ($node, $xpath, $attribute, $debug) = @_;
		my $value = '';
		if( $debug  ){
			print STDOUT "getAttributeOfNode $debug Xpath- \"$xpath\" Node Name: " . $node->nodeName. "\n";
		}
		$value = $node->findvalue($xpath . '/@' . $attribute );
		if( $debug  ){
			print STDOUT "getAttributeOfNode $debug value- \"$value\" \n";
		}
		return( $value);
	}
	sub getYNExpOfNode($$$$){
		my ($taskp, $startNode, $xPath, $debug ) = @_;
		my $val = '';
		$val = getAttributeOfNode( $startNode, $xPath, "val", $debug);
		my $exp = getAttributeOfNode( $startNode, $xPath, "Exp", $debug);
		if( $debug){
			print STDOUT "val:[$val], exp:[$exp]\n";
		}
		if( $val eq 'Y' || $val eq 'N'){
			$val = $yesno{$val};
		}
		elsif( $exp >= '1'){
			$val = expressionStringVar($taskp, $exp,0);
		}
		return ($val);
	}
	sub getNumExpOfNode($$$$){
		my ($taskp, $startNode, $xPath, $debug ) = @_;
		my $val = '';
		my $exp = getAttributeOfNode( $startNode, $xPath, "Exp", $debug);
		if( $debug){
			print STDOUT "val:[$val], exp:[$exp]\n";
		}
		if( $exp >= '1'){
#			print STDOUT "getNumExpOfNode $exp\n";
			$val = expressionStringVar($taskp, $exp, 0);
		}
		else {
			$val = getAttributeOfNode( $startNode, $xPath, "val", $debug);
		}
#		print STDOUT "getNumExpOfNode val $val\n";
		return ($val);
	}
	sub expressionStringVar($$$){
		my ($taskp, $id, $debug)=@_;
		my $exp = getAttributeOfNode($taskp,"Expressions/Expression[$id]/ExpSyntax", "val", 0);
		if( $id == 8888 || $debug ){
			print STDOUT "Expression 5: $exp\n";
			$debugEE = 1;
		}
		$exp = expandedExpression($exp) if $exp =~ /{\d+,\d+}/;
		$debugEE = 0;
		return ($exp);
	}
	sub printNodeNames(@$){
		my (@nodes, $block) = @_;
		if (@nodes eq 0){
			print STDOUT "printNodeNames: no nodes\n";
		}
		else {
			foreach $node (@nodes) {
				print STDOUT "printNodeNames: " .$node->nodeName, @taskNodes . "\n" if $block && $node->nodeName ne '#text';
				print STDOUT "printNodeNames: " .$node->nodeName, @taskNodes . "\n" if not $block;
			}
		}
	}
	sub condModDir($$$$){
		my ($taskp, $node, $doTabOut, $isPre) = @_;
		my $indent = 0;
		$Condition = getYNExpOfNode($taskp,  $node,"Condition", 0);
		$Modifier = getAttributeOfNode($node,"Modifier", "val", 0);
		$Direction = getAttributeOfNode($node,"Direction", "val", 0);
		print "\n" if ! $isPre;
		if( $isPre ){
			if( $Condition eq "Yes" ){
			}
			elsif( $Condition eq "No" ){
				print "\tNever do:\n";
				$indent = 1;
				$indentLevel++;
				tabOut();
				$indentLevel--;
			}
			else {
				print "\tIf( $Condition )\n";
				$indent = 1;
				$indentLevel++;
				tabOut();
				$indentLevel--;
			}
		}
		return( $indent );
	}
	sub printArguments($$$$$){
		my ($taskp, $parent, $isCom, $indent, $debug ) = @_;
		my $argN = 0;
		@Arguments = $parent->findnodes ("Arguments");
		if( @Arguments ){
			foreach $argument ($Arguments[0]->childNodes){# Under Arguments: Argument
				if( $argument->nodeName eq 'Argument'){
					$varName = '';
					$Parent = '';# value of 32768 means Main Program, blank means current, 1,2... means parent tasks.
					$Parent = getAttributeOfNode($argument,"Parent", "val", 0);
					$Argid = getAttributeOfNode($argument,"id", "val", 0);
					$ArgVariable ='';
					$ArgVariable = getAttributeOfNode($argument,"Variable", "val", 0);
					if( $ArgVariable eq '' ){
						$ArgVariable = $argument->getAttribute("Variable");
					}
					if($ArgVariable ne ''){
						if( $Parent eq ''){
							$Parent = 0;
						}
						$varName = varName("{$Parent,$ArgVariable}");
#						print STDOUT "varName of {$Parent,$ArgVariable} is \"$varName\" \n" if $ArgVariable == 14;
					}
					$ArgExpression ='';
					$ArgExpression = getAttributeOfNode($argument,"Expression", "val", 0);
					if ($ArgExpression eq '' ){
						$ArgExpression = getAttributeOfNode($argument,"Exp", "val", 0)
					}
					if($ArgExpression ne ''){
						$ArgExpression = expressionStringVar ($taskp, $ArgExpression,0);
					}

					$ArgSkip = getAttributeOfNode($argument,"Skip", "val", 0);
					$argN++;
					if( $argN == 1 && $indent ){
						print "\t";
					}
					print "\t\t$argN|";
					print "$varName" if $ArgExpression eq '';
					print "$ArgExpression";
					if( $ArgSkip eq 'Y'){
						print "!Parameter Skipped! ";
					}
					if( $isCom ){
						$ArgVType = $argtype{getAttributeOfNode($argument,"VT_Type", "val", 0)};
						$ArgName = getAttributeOfNode($argument,"Name", "val", 0);
						$ArgType = getAttributeOfNode($argument,"Type", "val", 0);
						print " as $ArgName $ArgVType as Type=$ArgType";
					}
					print "\n";
					if( $indent ){
						$indentOnce = 1;
					}
					tabOut();
				}
			}
		}
		
	}
	sub processTaskResources($$$){ #var pointing to Resources node
		my ($taskp, $taskchild, $isFirstPass) = @_;
		$DBcount = 0;
		foreach $resourceChild ($taskchild->childNodes){# Under Resource: DB, Columns
			$ResourceChildNodeName = $resourceChild->nodeName;
#			print STDOUT "ResourceChildNodeName: $ResourceChildNodeName \n" ;
			if( $ResourceChildNodeName eq 'IO'){
				$Description = getAttributeOfNode($resourceChild,"Description", "val", 0);
				$IOExpression = getAttributeOfNode($resourceChild,"IOExpression", "val", 0);
				$IOExpression = expressionStringVar($taskp, $IOExpression,0) if $IOExpression ne '';
				$OpenPrintDialog = getAttributeOfNode($resourceChild,"OpenPrintDialog", "val", 0);
				$PaperSize = getAttributeOfNode($resourceChild,"PaperSize", "val", 0);
				$Format = getAttributeOfNode($resourceChild,"Format", "val", 0);
				$Media = getAttributeOfNode($resourceChild,"Media", "val", 0);
				$Access = $mod{getAttributeOfNode($resourceChild,"Access", "val", 0)};
				$Copies = getAttributeOfNode($resourceChild,"Copies", "val", 0);
				$Orientation = getAttributeOfNode($resourceChild,"Orientation", "val", 0);
				$PrintPreview = getAttributeOfNode($resourceChild,"PrintPreview", "val", 0);
				$PDF = getAttributeOfNode($resourceChild,"PDF", "val", 0);
				$PrintingAllowed = getAttributeOfNode($resourceChild,"PrintingAllowed", "val", 0);
				$ContentCopyingAllowed = getAttributeOfNode($resourceChild,"ContentCopyingAllowed", "val", 0);
				$ChangesAllowed = getAttributeOfNode($resourceChild,"ChangesAllowed", "val", 0);
				$PageLayoutAllowed = getAttributeOfNode($resourceChild,"PageLayoutAllowed", "val", 0);
				$Vis2LogTranslation  = getAttributeOfNode($resourceChild,"Vis2LogTranslation", "val", 0);
				$FlipLines = getAttributeOfNode($resourceChild,"FlipLines", "val", 0);
				print "I/O: $Description on $IOExpression\n" if !$isFirstPass;

			}
			elsif( $ResourceChildNodeName eq 'DB'){
				$DataObjectNum = getAttributeOfNode($resourceChild,"DataObject", "obj", 0);
				$Access  = $mod{getAttributeOfNode($resourceChild,"Access", "val", 0)};
				$Share  = $mod{getAttributeOfNode($resourceChild,"Share", "val", 0)};
				$Open  = $read{getAttributeOfNode($resourceChild,"Open", "val", 0)};
				$Cache = $yesno{getAttributeOfNode($resourceChild,"Cache", "val", 0)};
				$IndentifyRowModifications = getAttributeOfNode($resourceChild,"IndentifyRowModifications", "val", 0);

				($DataObject,$DataFolder,$DataSource,$DsPhysName) = dataSourceName($DataObjectNum);

				if( !$isFirstPass ){
					$DBcount++;
					if( $DBcount == 1 ){
						print "\n// DB Files:\n";
						print "//+Fil+---- File Name ---------+Access+Share+--Open--+-----Cache------+-Exp---+---Folder---+-------DB Name--------+---DB File------+\n"; #601 re-align
					}
					$~ = 'DB_DETAIL';
					write;
				}
			}
			elsif( $ResourceChildNodeName eq 'Columns'){
				$v = 0;
				foreach $columnsChild ($resourceChild->childNodes){# Under Columns: Column
					$ColumnsChildNodeName = $columnsChild->nodeName;
					if( $ColumnsChildNodeName eq 'Column'){
						$ColumnName = $columnsChild->getAttribute( "name");
						$DefaultValue = getAttributeOfNode($columnsChild,"PropertyList/DefaultValue", "val", 0);
						$Model = 0;
						$Model = getAttributeOfNode($columnsChild,"PropertyList/Model", "obj", 0);

#						print STDOUT "ColumnName: $ColumnName [ $DefaultValue ]\n";

						$v++;
						if( $v == 1 && !$isFirstPass ){
							print "// Virtual Fields: \n";
							print "//#-+-- Name------ ---------------------------Model------------------------------Attribute------------ Picture -----Range--+\n";
						}
						if( $Model == 0 ){
							$ColumnDesc = getAttributeOfNode($columnsChild,"PropertyList/Model", "attr_obj", 0);
							if ( $ColumnDesc =~ /FIELD_(.+)/) {
								$ColumnAttr= ucfirst(lc($1)); #Capitalization or Initial Caps
							}
							$ColumnPic = getAttributeOfNode($columnsChild,"PropertyList/Picture", "valUnicode", 0);

							$~ = 'VIRTUAL_DETAIL';
						}
						else { $~ = 'VIRTUAL_M_DETAIL'; }
						write if !$isFirstPass;

						$virt[$p][$t][$v]->{desc}= $ColumnName;
						# find an example of a commented virtual
#									($comment) = $_ =~  /COMMENT="([^"]+)"/;
#									$virt[$p][$t][$v]->{comment}= $comment;

					}
				}
			}
		}
	}
	sub pushDbObj($){
		my ($obj) = @_;
#		print STDOUT "push $obj\n";
		($DbObjName, $DataFolder,$DataSource,$DsPhysName) = dataSourceName($obj );
		push @dbObjs, ($currentDb);
		$currentDb = $obj;
	}
	sub popDBObj(){
		my ($obj) = @_;
		$obj = pop @dbObjs;
		$currentDb = $obj;
		($DbObjName, $DataFolder,$DataSource,$DsPhysName) = dataSourceName($obj );
#		print  "pop ---obj:$obj dbObjName:$DbObjName\n";
	}
	sub printLNK($$$){
		my ($taskp, $logicLineChild,$isFirstPass) = @_;
		
		$DbObj = getAttributeOfNode($logicLineChild,"DB", "obj", 0);
		if( ! $isFirstPass){
			$Direction = $ascDesc{$logicLineChild->getAttribute( "Direction")};
			$Evl_Cnd = $logicLineChild->getAttribute( "EVL_CND");
			$ReturningFieldID = $logicLineChild->getAttribute( "FieldID");#for returned values - not always here
			$ReturningFieldID = varName( "{0,". $ReturningFieldID . "}" ) if $ReturningFieldID ne '';
			$FlowIsn = $logicLineChild->getAttribute( "FlowIsn");
			$Key = $logicLineChild->getAttribute( "Key");
			$Mode = $lnkmod{$logicLineChild->getAttribute( "Mode")};
			$SortType = $logicLineChild->getAttribute( "SortType");
			$View = $logicLineChild->getAttribute( "VIEW");
			$Views = $logicLineChild->getAttribute( "VIEWS");
			$Expanded = getAttributeOfNode($logicLineChild,"Expanded", "val", 0);
			$Condition = getAttributeOfNode($logicLineChild,"Condition", "val", 0);
		}
		pushDbObj($DbObj);
		if( ! $isFirstPass ){
			$KeyName = '';
			$KeyName = dataSourceIndexName( $DbObj, $Key ) if $Key ne '';

			print "\tLink $Mode $DbObj $DbObjName Key: $Key $KeyName Dir: $Direction ";
			print "  Returning: $ReturningFieldID" if $ReturningFieldID ne '';

			$indentLevel++;
			print "\n";
		}
	}
	sub printSelect($$$$){
		my ($taskp, $logicLineChild,  $doTabOut, $isFirstPass) = @_;
		
		$FieldID = $logicLineChild->getAttribute( "FieldID");
		$id = $logicLineChild->getAttribute( "id");
		$Column = getAttributeOfNode($logicLineChild,"Text", "val", 0);
		$ColumnVal = getAttributeOfNode($logicLineChild,"Column", "val", 0);#for reals
		$Type = $realvirt{getAttributeOfNode($logicLineChild,"Type", "val", 0)};#Real Virtual

		if(! $isFirstPass){
			$IsParameter = getAttributeOfNode($logicLineChild,"IsParameter", "val", 0);
			$LocateMax = getAttributeOfNode($logicLineChild,"Locate", "MAX", 0);
			$LocateMin = getAttributeOfNode($logicLineChild,"Locate", "MIN", 0);
			$RangeMax = getAttributeOfNode($logicLineChild,"Range", "MAX", 0);
			$RangeMin = getAttributeOfNode($logicLineChild,"Range", "MIN", 0);
			$Assign = '';
			$Assign = getAttributeOfNode($logicLineChild,"ASS", "val", 0);

			$LocateMin = getAttributeOfNode($logicLineChild,"Expressions/Expression[$LocateMin]", "val", 0) if $LocateMin ne '';
			$LocateMax = getAttributeOfNode($logicLineChild,"Expressions/Expression[$LocateMax]", "val", 0) if $LocateMax ne '';
			$RangeMin = getAttributeOfNode($logicLineChild,"Expressions/Expression[$RangeMin]", "val", 0) if $RangeMin ne '';
			$RangeMax = getAttributeOfNode($logicLineChild,"Expressions/Expression[$RangeMax]", "val", 0) if $RangeMax ne '';

			if( $IsParameter eq 'Y'){
				$par++;
				print $par;
			}
		}
		if( $Type eq 'Real') {
			print "\t\tReal:$DbObjName." if ! $isFirstPass;
			print STDOUT "currentDb?\n" if $currentDb eq '';
			$columnName = dataSourceFieldName($currentDb, $ColumnVal, 0);
			if( $columnName eq ''){ #should not happen
				print STDOUT "currendDb $currentDb, dn:$DbObjName, cv:$ColumnVal \n";
			}
			print $columnName if ! $isFirstPass;
			$FieldName = "$DbObjName.$columnName";
		}
		elsif ($Type eq 'Virt'){  #not sure to use FieldID or id, or something else.
			$desc = getAttributeOfNode ( $taskp, "Resource/Columns/Column[".$ColumnVal."]",'name', 0);
			print "\tVirt:$desc" if ! $isFirstPass;
			$FieldName = $desc;
		}
		else{
			print "\t??Unknown Select Type??" if ! $isFirstPass;
		}
#		if( $isFirstPass ){
#			print STDOUT "fields $fields [ $HierLevelT ][ $id ]->{name} = $FieldName\n" if $id == 1;
		#THis may be redundant for Main flow selects but not for selects in handlers
			$fields[$HierLevelT][$id]->{name} = $FieldName;
#		}
		if( ! $isFirstPass ){
			if( $Assign ne '' ){
				$Assign = expressionStringVar($taskp, $Assign,0);
				print "\t=\t $Assign ";
			}
			if($LocateMin eq $LocateMax and $LocateMin ne '' ){
				print "\tLocate == $LocateMin\n";
			}
			else {
				if( $LocateMin ne ''){
					print "\tLocate\tFrom: $LocateMin";
					if( $LocateMax ne ''){
						print  '\n';
					}
				}
				print "\tLocate\tTo:$LocateMax" if $LocateMax ne '';
			}
			if($RangeMin eq $RangeMax and $RangeMin ne ''){
				print "\tRange == $RangeMin\n";
			}
			else {
				if( $RangeMin ne ''){
					print "\tRange\tFrom: $RangeMin";
					if( $RangeMax ne ''){
						print  '\n';
	#					tabOut();
					}
				}
				print "\tRange\tTo:$RangeMax" if $RangeMax ne '';
			}
			condModDir($taskp, $logicLineChild, $doTabOut, 0);
		}
	}
	sub printCallTask($$){
		my ($taskp, $logicLineChild) = @_;
		my $dodebug = 0;
		$OperationType = getAttributeOfNode($logicLineChild,"OperationType", "val", 0);
		$TaskID = getAttributeOfNode($logicLineChild,"TaskID", "obj", 0);#could be Task or Program
		if( $OperationType eq 'P' ){
			$dodebug = 1 if $TaskID == 1199;
			$TaskID = $ph[$TaskID]->{desc};
		}
		elsif( $OperationType eq 'T' ){
			$TaskID = taskName ($taskp, $TaskID );
		}
		elsif( $OperationType eq 'E' ){
			#$TaskID = getAttributeOfNode( $ph_data, "//Application/ProgramsRepositoryHeaders/Program[$TaskID]/Header","Description", 0);
		}
		elsif( $OperationType eq 'U' ){
			#$TaskID = getAttributeOfNode( $ph_data, "//Application/ProgramsRepositoryHeaders/Program[$TaskID]/Header","Description", 0);
		}
		else{
			#$TaskID = getAttributeOfNode( $ph_data, "//Application/ProgramsRepositoryHeaders/Program[$TaskID]/Header","Description", 0);
		}
		$Lock = getAttributeOfNode($logicLineChild,"Lock", "val", 0);
		$Wait = getAttributeOfNode($logicLineChild,"Wait", "val", 0);
		$SyncData = getAttributeOfNode($logicLineChild,"SyncData", "val", 0);

		$OperationType = $optype{$OperationType};
		$indent = condModDir($taskp, $logicLineChild, 1, 1);
		print "\tCall $OperationType: $TaskID ";
		print "  Wait" if $Wait eq 'Y';
		
		print "  SyncData" if $SyncData eq 'Y';
		print "\n";
		tabOut();
		printArguments($taskp, $logicLineChild, 0, $indent, $dodebug);
	}
	sub printInvoke ($$){
		my ($taskp, $logicLineChild )= @_;

		$OperationType = getAttributeOfNode($logicLineChild,"OperationType", "val", 0);#C = COM, U=User
		$Command = getAttributeOfNode($logicLineChild,"Command", "val", 0);
		$Wait = getAttributeOfNode($logicLineChild,"Wait", "val", 0);
		$Show = getAttributeOfNode($logicLineChild,"Show", "val", 0);
		$SyncData = getAttributeOfNode($logicLineChild,"SyncData", "val", 0);
		$indent = condModDir($taskp, $logicLineChild, 1, 1);
		if( $OperationType eq 'C'){
			$Option = 'Call Method';
			$Option = $invopt{getAttributeOfNode($logicLineChild,"Option", "val", 0)};
			$FieldID2 = $logicLineChild->getAttribute('FieldID2');
			$FieldID2 = getAttributeOfNode ( $taskp, "Resource/Columns/Column[".$FieldID2."]",'name', 0) if $FieldID2 ne '';
			$MethodName = getAttributeOfNode($logicLineChild,"MethodName", "val", 0);
			if($MethodName eq ''){
				$MethodName = "Active Connection";
			}
			print "\tCall COM: $FieldID2\.$MethodName, Option:$Option, Wait: $Wait Sync: $SyncData ";
		}
		elsif($OperationType eq 'U'){
			$TaskID = getAttributeOfNode($logicLineChild,"TaskID", "obj", 0);
			$TaskID = expressionStringVar($taskp, $TaskID,0);
			print "\tCall UDP:$TaskID  Wait: $Wait Sync: $SyncData ";
		}
		print " Cmd:$Command  " if $Command ne '';
		print " Show:$Show" if $Show ne '';  
		#print " Op:$OperationType" if $OperationType ne '' ; 
		print "\n";
		tabOut();
		printArguments($taskp, $logicLineChild, $OperationType eq 'C', $indent, 0);
	}
	sub processTaskLogic($$$$){ #var pointing to TaskLogic node
		my ($taskp, $taskLogic, $isFirstPass,$mainFileNbr)=@_;
		#for first pass, only interested in Record Main
		my @LogicLines;
		my $logicLines;
		my $logicLine;
		my $logicUnit;
#		print STDOUT "TaskLogic: " .$taskLogic->nodeName . "\n";
		foreach $logicUnit ($taskLogic->childNodes){# Under TaskLogic: LogicUnit
			if ($logicUnit->nodeName eq 'LogicUnit'){
				$indentLevel = 1;
				$LUID = $logicUnit->getAttribute("id");
				$TXT = getAttributeOfNode($logicUnit,"TXT", "val", 0);  
				$Type = $evttype{getAttributeOfNode($logicUnit,"Event/EventType", "val", 0)};  #for first pass- System
				$Level = $brkcontext{getAttributeOfNode($logicUnit,"Level", "val", 0)}; #for first pass- Record
				$BrkType = $brktype{getAttributeOfNode($logicUnit,"Type", "val", 0)}; #for first pass- Main
				$isSystemRecordMain = $Type=='System' && $Level eq 'Record' && $BrkType eq 'Main';
				if( ! $isFirstPass ) {
					$Scope = $eventscope{getAttributeOfNode($logicUnit,"Scope", "val", 0)};
					$EngineDirective = $engDir{getAttributeOfNode($logicUnit,"EngineDirective", "val", 0)};
					$FieldID = getAttributeOfNode($logicUnit,"FieldID", "val", 0);
					$_TotalVariabls = getAttributeOfNode($logicUnit,"_TotalVariabls", "val", 0);
					$_TotalVirtuals = getAttributeOfNode($logicUnit,"_TotalVirtuals", "val", 0);

					$eKeyCombo = getAttributeOfNode($logicUnit,"Event/KeyCombinationID", "val", 0);
					if( $eKeyCombo ne ''){
						$eKeyCombo = "Key:" . $eKeyCombo . ' ' . $key_from_col4{$eKeyCombo};
						$FieldID = '';# blank it.
					}
					if( $FieldID ne '' ){
						$FieldID = "Field: " . varName("{0,$FieldID}");
					}

					$eDesc = '';
					if($Type eq 'User'){
						$PublicObject = getAttributeOfNode($logicUnit,"Event/PublicObject", "obj", 0);
						$Parent = '';# value of 32768 means Main Program, blank means current, 1,2... means parent tasks.
						$Parent = getAttributeOfNode($logicUnit,"Event/Parent", "val", 0);
						if( $Parent eq ''){
							$Parent = 0;
						}
						$eventLevel = 32768;
						if( $Parent != 32768 ){
							$eventLevel = $HierLevelT - $Parent;
						}
						$eDesc = $evntName[$eventLevel][$PublicObject];
	#					print STDOUT "Operations: LUID:$LUID Level:$Level Type:$Type eDesc:$eDesc Scope:$Scope EngineDir:$EngineDirective eLevel:$eventLevel Hier:$HierLevelT  Parent:$Parent Obj:$PublicObjectObj;\n";
						print "\nOperations: $LUID $Type $Level $eDesc $Scope\n";
					}
					elsif ($Type eq 'Error'){
							$ErrorTrigger = $errorList{getAttributeOfNode($logicUnit,"Event/ErrorTrigger", "val", 0)};
							if( $ErrorTrigger eq ''){
								 $ErrorTrigger = 'Any';
							}
							print "\nOperations: $LUID $Type $Level $ErrorTrigger $Scope $EngineDirective\n";
					}
					elsif ($Type eq 'System'){
						if( $BrkType eq 'User'){
							print "\nOperations: $LUID $Type  $Level $BrkType $eKeyCombo $FieldID $Scope\n";
						}
						else {
							print "\nOperations: $LUID $Type  $Level $BrkType $Scope\n";
						}
					}
					elsif ($Type eq 'Internal'){
						my $On = '';
						if( $TXT ne ''){
							$On = "On: $TXT";
						}
						$ErrorTrigger = $errorList{getAttributeOfNode($logicUnit,"Event/ErrorTrigger", "val", 0)};
						print "\nOperations: $LUID $Type $Level $BrkType $eKeyCombo $On $Scope \n";
					}
					else {
						print "\nOperations: unexpected $LUID $Level $Type  $eDesc $eKeyCombo $FieldID $Scope\n";
					}
				}
#				print STDOUT "LogicUnit: $LUID $Level $Type $eDesc $Scope $EngineDirective\n";
				if(!$isFirstPass || $isSystemRecordMain  ){
					@LogicLines = $logicUnit->findnodes ("LogicLines");
					foreach $logicLines (@LogicLines){
						$par = 0;
						foreach $logicLine ($logicLines->childNodes){# Under TaskLogic: LogicUnit
	#						print STDOUT "LogicLine: " .$logicLine->nodeName . "\n" ;
							if($logicLine->nodeName ne "#text" ){
								foreach $logicLineChild ($logicLine->childNodes){# Under LogicLine: DATAVIEW_SRC
									$logicLineChildName = $logicLineChild->nodeName;
#									print STDOUT "Logiclinechild: " .$logicLineChild->nodeName . "\n" if $logicLineChild->nodeName ne "#text" && $isFirstPass;
									if ($logicLineChildName eq 'DATAVIEW_SRC' ){
										$Type = $logicLineChild->getAttribute( "Type");
										pushDbObj($mainFileNbr);
										print "\tDataview Src: $Type "  if !$isFirstPass;#what is this?
										condModDir($taskp, $logicLineChild, 1, 0) if !$isFirstPass;
									}
									elsif ( $logicLineChildName eq 'Select' ){
										printSelect($taskp, $logicLineChild,1, $isFirstPass);
									}
									elsif ( $logicLineChildName eq 'Remark' && !$isFirstPass  ){
										if ( !$isFirstPass ){
											$Type = getAttributeOfNode($logicLineChild,"Type", "val", 0);#Types are 0 or 2. What does it mean?
											$Text = getAttributeOfNode($logicLineChild,"Text", "val", 0);

											if ( $Text eq ' ')	{
												print "\t//------------------------------------------------------------------------- \n";
											}
											else			{
												print "\t// $Text \n";
											}
											tabOut();
										}
									}
									elsif ( $logicLineChildName eq 'LNK' ){
										printLNK($taskp, $logicLineChild, $isFirstPass);
									}
									elsif ( $logicLineChildName eq 'END_LINK' ){
										$indentLevel--;
										$lnkref = '';
										popDBObj();
										tabOut() if ! $isFirstPass;
									}
									elsif ( $logicLineChildName eq 'Update' && !$isFirstPass  ){ #{Parent val, FieldID val }
										my $Parent = '';# value of 32768 means Main Program, blank means current, 1,2... means parent tasks.
										my $varName = '';
										my $FieldID = '';
										my $WithValue = '';
										$Parent = getAttributeOfNode($logicLineChild,"Parent", "val", 0);
										$FieldID = getAttributeOfNode($logicLineChild,"FieldID", "val", 0);
										$WithValue = getAttributeOfNode($logicLineChild,"WithValue", "val", 0);
										if( $Parent eq ''){
											$Parent = 0;
										}
										if( $FieldID ne ''){
	#										print STDOUT "varName of {$Parent,$FieldID} \n" if $FieldID == 77;
											$varName = varName("{$Parent,$FieldID}");
	#										$FieldID = getAttributeOfNode ( $taskp, "Resource/Columns/Column[".$FieldID."]",'name', 0);
										}
										if( $WithValue ne '') {
											$WithValue = expressionStringVar($taskp, $WithValue,0);
										}
										condModDir($taskp, $logicLineChild, 1, 1);
										print "\t$varName\t=\t$WithValue\n";
										tabOut();
									}
									elsif ( $logicLineChildName eq 'CallTask' && !$isFirstPass){
										printCallTask($taskp, $logicLineChild);
									}
									elsif ( $logicLineChildName eq 'Evaluate' && !$isFirstPass){
										$Expression = getAttributeOfNode($logicLineChild,"Expression", "val", 0);
										$Expression = expressionStringVar($taskp, $Expression,0);

										condModDir($taskp, $logicLineChild, 1, 1);
										print "\tEvaluate: $Expression";
										print "\n";
										tabOut();
									}
									elsif ( $logicLineChildName eq 'BLOCK' && !$isFirstPass){
										if (!$isFirstPass){

											$BlockType = $blocktype{$logicLineChild->getAttribute("Type")};

											$Modifier = getAttributeOfNode($logicLineChild,"Modifier", "val", 0);
											$Direction = getAttributeOfNode($logicLineChild,"Direction", "val", 0);
											$Condition = getYNExpOfNode($taskp,  $logicLineChild,"Condition", 0);

											if($BlockType eq 'If'){#If
												$indentLevel++;			
												$lastIfBlockCond = $Condition;
												if ( $Condition eq 'Yes' ) { print "\tDo:" ;												}
												elsif ( $Condition eq 'No' )  { print "\tNever do:" ;												}
												else { print "\tDo if ( $Condition ):"; }
											}
											elsif($BlockType eq 'Else'){#Else
												if ( $Condition eq 'Yes' ) {   print "Else Do:" ; }
												elsif ( $Condition eq 'No' )  { print "Else never do:" ; }
												else { print "Else Do If ( $Condition ):"; }
											}
											elsif($BlockType eq 'Loop'){#loop mode, like if with condition
												$indentLevel++;			
												if ( $Condition eq 'Yes' ) { print "\tLoop forever:" ; } 	# probably impossible.  A loop without condition is like a loop forever.
												elsif ( $Condition eq 'No' )  { print "\tNever Loop:" ; }
												else { print "\tLoop while ( $Condition ):"; }
											}
											else {
												print "?Block Mode?";
											}
#											print "($indentLevel)";
											print "\n";
											tabOut();
										}
									}
									elsif ( $logicLineChildName eq 'END_BLK' && !$isFirstPass){
										$indentLevel--;
									}
									elsif ( $logicLineChildName eq 'RaiseEvent' && !$isFirstPass){
										$EventType = $evttype{getAttributeOfNode($logicLineChild,"Event/EventType", "val", 0)};
										$Wait = getAttributeOfNode($logicLineChild,"Wait", "val", 0);
										$eDesc = '';
										$indent = condModDir($taskp, $logicLineChild, 1, 1);
										if( $EventType eq 'User'){
											$Parent = '';# value of 32768 means Main Program, blank means current, 1,2... means parent tasks.
											$Parent = getAttributeOfNode($logicLineChild,"Event/Parent", "val", 0);
											if( $Parent eq ''){
												$Parent = 0;
											}
											$eventLevel = 32768;
											if( $Parent != 32768 ){
												$eventLevel = $HierLevelT - $Parent;
											}
											$PublicObject = getAttributeOfNode($logicLineChild,"Event/PublicObject", "obj", 0);# for User events
											$eDesc = $evntName[$eventLevel][$PublicObject];
											print "\tRaise Event: User $eDesc";
										}
										elsif( $EventType eq 'Internal'){
											$InternalEventID = getAttributeOfNode($logicLineChild,"Event/InternalEventID", "val", 0);
											$InternalEvent = $action_from_code{ $InternalEventID };
											print "\tRaise Event: Internal $InternalEventID $InternalEvent";
										}
										elsif( $EventType eq 'System'){
#											$eDescCode = $eDesc;
#											$eDesc = $action_from_code{$eDescCode};
											print "\tRaise Event: System  $eDesc";
										}
										elsif( $EventType eq 'Error'){
											$ErrorTrigger = $errorList{getAttributeOfNode($logicLineChild,"Event/ErrorTrigger", "val", 0)};
											print "\tRaise Event: Error $ErrorTrigger";
										}
										elsif( $EventType eq 'None'){
											print "\tRaise Event: None";
										}
										else{
											print "\tRaise Event: ??unknown?? $eDesc";
										}
										print "\n";
										tabOut();
										printArguments($taskp, $logicLineChild, 0, $indent, 0);
									}
									elsif ( $logicLineChildName eq 'STP' && !$isFirstPass ){
										$StopMode = $stpmod{$logicLineChild->getAttribute("Mode")};
										$StopText = $logicLineChild->getAttribute("TXT");#either there is text or expression - not both.
										$StopExp = $logicLineChild->getAttribute("Exp");
										condModDir($taskp, $logicLineChild, 1, 1);
										print "\tPut $StopMode ";
										print "$StopText" if $StopText ne '';
										print "$StopExp" if $StopText eq '';

										print "\n";
										tabOut();
									}
									elsif ( $logicLineChildName eq 'FormIO' && !$isFirstPass){#formerly write/read
										$FlowIsn = $logicLineChild->getAttribute ("FlowIsn");
										$OperationType = $formio_op{getAttributeOfNode($logicLineChild,"OperationType", "val", 0)};
										$FormEntryIndex = getAttributeOfNode($logicLineChild,"FormEntryInfo/FormEntryIndex", "val", 0);
										$FormName = formName($taskp, $FormEntryIndex);
										$IoDeviceIndex = getAttributeOfNode($logicLineChild,"IoDeviceInfo/IoDeviceIndex", "val", 0);

										condModDir($taskp, $logicLineChild, 1, 1);
										print "\t$OperationType Form: $FormEntryIndex $FormName on $IoDeviceIndex ($FlowIsn)";
										print "\n";
										tabOut();
									}
									elsif ( $logicLineChildName eq 'Screen' && !$isFirstPass ){
										print "\tScreen";
									}
									elsif ( $logicLineChildName eq 'EXT' && !$isFirstPass){
										condModDir($taskp, $logicLineChild, 1, 1);
										print "\tExit to: ";
										print "\n";
										tabOut();
									}
									elsif ( $logicLineChildName eq 'Invoke' && !$isFirstPass){#Call COM
										printInvoke($taskp, $logicLineChild);
									}
									elsif ( $logicLineChildName eq '#text' && !$isFirstPass){
									}
									elsif (!$isFirstPass) {
										print STDOUT "Unknown?? logicLineChild $logicLineChildName\n";
									}
								}
							}
						}
					}
				}
			}
		}
	}
						 sub printComment($$){
		my ($Comment, $prebreak) = @_;
		if( $Comment ne '' ){
			print "\n" if $prebreak eq 'Y';
			print "-------------------------------\nComment:\n$Comment\n";
			print "-------------------------------";
			print "\n" if $prebreak eq 'Y';
		}
	}
	sub processTaskForm($$){
		# only called from getPrgResources10
		my ($taskp, $taskchild) = @_;
		foreach $FormEntry ($taskchild->childNodes){
			$FormEntryName = $FormEntry->nodeName;
			if( $FormEntryName eq 'FormEntry' ){
				$Model = getAttributeOfNode($FormEntry,"PropertyList","model", 0);
				$Placement = getAttributeOfNode($FormEntry,"PropertyList/Placement","val", 0);

				$Top    = getNumExpOfNode( $taskp, $FormEntry,"PropertyList/Top", 0 );
				$Width  = getNumExpOfNode( $taskp, $FormEntry,"PropertyList/Width", 0 );
				$Height = getNumExpOfNode( $taskp, $FormEntry,"PropertyList/Height", 0 );

				$Font       = getAttributeOfNode($FormEntry,"PropertyList/Font","val", 0);
				$_Comment   = getAttributeOfNode($FormEntry,"PropertyList/_Comment","val", 0);
				$FormName   = getAttributeOfNode($FormEntry,"PropertyList/FormName","valUnicode", 0);
				$WindowType = getAttributeOfNode($FormEntry,"PropertyList/WindowType","val", 0);
				$GridX	    = getAttributeOfNode($FormEntry,"PropertyList/GridX","val", 0);
				$GridY      = getAttributeOfNode($FormEntry,"PropertyList/GridY","val", 0);
				$HorizontalFactor = getAttributeOfNode($FormEntry,"PropertyList/HorizontalFactor","val", 0);
				$VerticalFactor = getAttributeOfNode($FormEntry,"PropertyList/VerticalFactor","val", 0);
				$HorizFactor = 4 if $HorizFactor eq '';
				$VertFactor  = 8 if $VertFactor eq '';

				print "\nForm: \"$FormName\"  ";

				print ", F:$Font" if $Font ne '';
				print ", WT:$WindowType" if $WindowType ne '';
				print ", T:$Top (".$Top/$VertFactor.")" if $Top ne '';
				print ", W:$Width (".$Width/$HorizFactor.")" if $Width ne '';
				print ", H:$Height (".$Height/$VertFactor.")" if $Height ne '';
				print "\n";

				foreach $Control ($FormEntry->childNodes){
					$ControlName = $Control->nodeName;
#					print STDOUT "Control $ControlName\n";
					if( $ControlName eq 'Control' ){
						$id = $Control->getAttribute("id");
#						print STDOUT "Control $id \n";
						$Top = getNumExpOfNode( $taskp, $Control,"PropertyList/Top", 0 );
						$Width = getNumExpOfNode( $taskp, $Control,"PropertyList/Width", 0 );
						$Height = getNumExpOfNode( $taskp, $Control,"PropertyList/Height", 0 );
						$Height = getNumExpOfNode( $taskp, $Control,"PropertyList/Height", 0 );

						$ISN_FATHER = $Control->getAttribute("ISN_FATHER");
						$Model = getAttributeOfNode($Control,"PropertyList","model", 0);
						$Color = getNumExpOfNode($taskp, $Control,"PropertyList/Color", 0);
						$Visible = getAttributeOfNode($Control,"PropertyList/Visible","Exp", 0);
						if( $Visible ne ''){
							$Visible = expressionStringVar($taskp, $Visible , 0);
						}
						$Style = getAttributeOfNode($Control,"PropertyList/Style","val", 0);
						$BorderStyle = getAttributeOfNode($Control,"PropertyList/BorderStyle","val", 0);
						$TitleHeight = getAttributeOfNode($Control,"PropertyList/TitleHeight","val", 0);
						$RowHeight = getAttributeOfNode($Control,"PropertyList/RowHeight","val", 0);
						$Elements = getAttributeOfNode($Control,"PropertyList/Elements","val", 0);
						$AllowColumnResize = getAttributeOfNode($Control,"PropertyList/AllowColumnResize","val", 0);
						$MultiMarking = getAttributeOfNode($Control,"PropertyList/MultiMarking","val", 0);
						$_Before900Version = getAttributeOfNode($Control,"PropertyList/_Before900Version","val", 0);
						$_WindowWidth = getAttributeOfNode($Control,"PropertyList/_WindowWidth","val", 0);
						$LastDivider = getAttributeOfNode($Control,"PropertyList/LastDivider","val", 0);
						$ControlName = getAttributeOfNode($Control,"PropertyList/ControlName","val", 0);

						if( $Model =~ /_COLUMN/ ){
							#Column only
							$MarkingColumn = getAttributeOfNode($Control,"PropertyList/MarkingColumn","val", 0);
							$ColumnTitle = getAttributeOfNode($Control,"PropertyList/ColumnTitle","valUnicode", 0);
							print "\tControl Column Title: $id $Model \"$ColumnTitle\" $MarkingColumn ";
						}
						elsif ($Model =~ /_EDIT/ ){#Two types so far CTRL_TEXT_EDIT, CTRL_GUI0_EDIT
							#Edit Only
							$ControlEditModel = getAttributeOfNode($Control,"PropertyList/Model","ID", 0);

							$ControlEditData = getAttributeOfNode($Control,"PropertyList/Data","Exp", 0);
							$ControlEditData = expressionStringVar($taskp, $ControlEditData,0) if $ControlEditData ne '';

							$ControlEditVar = getAttributeOfNode($Control,"PropertyList/Model/Var","FieldID", 0);
							$ControlEditVar = getAttributeOfNode ( $taskp, "Resource/Columns/Column[$ControlEditVar]",'name', 0) if $ControlEditVar ne '';

							$ControlLayer = getAttributeOfNode($Control,"PropertyList/ControlLayer","val", 0);
							print "\tControl Edit: $id $Model $ControlEditModel \"$ControlEditVar$ControlEditData\"  ";
						}
						elsif ( $Model =~ /_STATIC/ ){
							$Text = getAttributeOfNode($Control,"PropertyList/Text","valUnicode", 0);
							print "\tControl Static: $id $Model \"$Text\" ";
						}
						else {
							print "\tControl: $id $Model ";
						}
						print ", N:\"$ControlName\" " if $ControlName ne '';
						print ", F:$ISN_FATHER" if $ISN_FATHER ne '';
						print ", L:$Left (".$Left/$HorizFactor.")" if $Left ne '';
						print ", T:$Top (".$Top/$VertFactor.")" if $Top ne '';
						print ", W:$Width (".$Width/$HorizFactor.")" if $Width ne '';
						print ", H:$Height (".$Height/$VertFactor.")" if $Height ne '';
						print ", C:$Color" if $Color ne '';
						print ", V:$Visible" if $Visible ne '';
						print "\n";
					}
				}
			}
		}
	}
	sub processSQL_FORM($$){
		my ($taskp, $taskchild) = @_;
		$sqlDb = $taskchild->getAttribute ("DB");
		$sqlRestab = $taskchild->getAttribute ("RESTAB");
		$sqlStatement = getAttributeOfNode($taskchild,"SQL_STMT_U","val", 0);
		print "----------------SQL Command ---------------------\n";
		print "DbIn: $sqlDb  DbOut: $sqlRestab \n";
		print "SqlCmd: $sqlStatement \n\n";
		foreach $argGroup ($taskchild->childNodes){
			if( $argGroup->nodeName eq 'OUTARG'){
				print "Outputs:\n";
				printArguments($taskp, $argGroup, 0, 0, 0);
			}
			elsif( $argGroup->nodeName eq 'INARG'){
				print "Inputs:\n";
				printArguments($taskp, $argGroup, 0, 0, 0);
			}
		}
	}
	# Quick XML:LibXML Reference Card
	# Useful link: http://refcards.com/docs/forda/perl-xml-libxml/perl-xml-libxml-refcard-a4.pdf
	# nodeType returns 3 for #text nodes
	# normalize does nothing.
	sub	getPrgResources10($$) {
		my ($tp, $HierLevel) = @_;
		my $taskLogic;
		$HierLevelT = $HierLevel;
#		my $scalar_ref = \$tp;
		if( $HierLevel == 1 ){ $gpr = 0; }
		if( $gpr++ > 60 ){#if we get to this level, its out of control.
			print STDOUT "Max number of Tasks Exceeded !!\n";
			exit;
		}
		if( $HierLevel > 10 ){#if we get to this level, its out of control.
			print STDOUT "Max depth of Tasks Exceeded !!\n";
			exit;
		}
#		print STDOUT "getPrgResources10 $HierLevel -- $gpr $scalar_ref \n";#xxx
		$t++;
		$eventn = 0;# just added this in 940-10
		initTaskVarsPrescan();
#		print STDOUT "initTaskVarsPrescan\n" if $HierLevel>1;
		#pass 1 activities.  Need to pre assign Resources and Record Main / Dataview before eval of expressions.
		foreach $rp ($tp->findnodes("Resource")){#note the form names
			processTaskResources($tp, $rp,1); #var pointing to Resources node
		}
#		print STDOUT "pre processTaskLogic\n" if $HierLevel>1;		
		$mainFileNbr = getAttributeOfNode($tp,"Information/DB","obj", 0);
		foreach $taskLogic ($tp->findnodes("TaskLogic")){#note the form names
			processTaskLogic($tp, $taskLogic, 1, $mainFileNbr); #var pointing to TaskLogic node
		}
#		print STDOUT "past processTaskLogic\n" if $HierLevel>1;		
		$TaskType = getAttributeOfNode($tp,"Header/TaskType","val", 0);
		$Comment = getAttributeOfNode($tp,"Header/Comment","val", 0);
		$Resident = getAttributeOfNode($tp,"Header/Resident","val", 0);

		$queryRight = getAttributeOfNode($tp,"Header/QueryRight","val", 0);
		$modifyRight = getAttributeOfNode($tp,"Header/ModifyRight","val", 0);
		$deletionRight = getAttributeOfNode($tp,"Header/DeletionRight","val", 0);
		$executionRight = getAttributeOfNode($tp,"Header/ExecutionRight","val", 0);
		if( $queryRight eq '') {$queryRight = 'None';}
		if( $modifyRight eq '') {$modifyRight = 'None';}
		if( $deletionRight eq '') {$deletionRight = 'None';}
		if( $executionRight eq '') {$executionRight = 'None';}

		$mainFileName = '';
		$mainFileIdxDesc = '';
		$mainFileNbr = getAttributeOfNode($tp,"Information/DB","obj", 0);
		$mainFileIdxNbr = getAttributeOfNode($tp,"Information/Key/Column","val", 0);
		$mainFileIdxExp = getAttributeOfNode($tp,"Information/Key/Exp","val", 0);
		$mainFileIdxMode = $ascDesc{getAttributeOfNode($tp,"Information/Key/Mode","val", 0)};
		$ForceRecordDelete = getAttributeOfNode( $tp, "Information/ForceRecordDelete", "DEL", 0);
		$EndTaskCondition = getAttributeOfNode( $tp, "Information/EndTaskCondition", "val", 0);
		if( $EndTaskCondition eq '' ){
			$EndTaskCondition = getAttributeOfNode( $tp, "Information/EndTaskCondition", "Exp", 0);
			$EndTaskCondition = expressionStringVar($tp, $EndTaskCondition, 0) if $EndTaskCondition ne '';
		}
		else {
			$EndTaskCondition = $yesno{$EndTaskCondition};
		}
		$EvaluateEndCondition = getAttributeOfNode( $tp, "Information/EvaluateEndCondition", "val", 0);
		$InitialMode	= getAttributeOfNode( $tp, "Information/InitialMode", "val", 0);

		$LocateDir		= $ascDesc{getAttributeOfNode( $tp, "Information/Locate", "Direction", 0)};
		$RangeDir		= $ascDesc{getAttributeOfNode( $tp, "Information/Range", "Direction", 0)};

		$LocateExp		= getAttributeOfNode( $tp, "Information/Locate", "Exp", 0);
		$LocateExp		=  expressionStringVar ($tp, $LocateExp,0) if $LocateExp ne '';
		$LocateExp		=  "None Defined" if $LocateExp eq '';#00u01

		$RangeExp		= getAttributeOfNode( $tp, "Information/Range", "Exp", 0);
		$RangeExp		=  expressionStringVar ($tp, $RangeExp,0) if $RangeExp ne '';
		$RangeExp		=  "None Defined" if $RangeExp eq '';#00u01

		$AllowOptions	= getYNExpOfNode($tp, $tp,"Information/SIDE_WIN/AllowOptions", 0);
		$AllowQuery		= getYNExpOfNode($tp, $tp,"Information/SIDE_WIN/AllowQuery", 0);
		$AllowModify	= getYNExpOfNode($tp, $tp,"Information/SIDE_WIN/AllowModify", 0);
		$AllowCreate	= getYNExpOfNode($tp, $tp,"Information/SIDE_WIN/AllowCreate", 0);
		$AllowDelete	= getYNExpOfNode($tp, $tp,"Information/SIDE_WIN/AllowDelete", 0);
		$AllowLocate	= getYNExpOfNode($tp, $tp,"Information/SIDE_WIN/AllowLocate", 0);
		$AllowRange		= getYNExpOfNode($tp, $tp,"Information/SIDE_WIN/AllowRange", 0);
		$AllowKeyChange = getYNExpOfNode($tp, $tp,"Information/SIDE_WIN/AllowIndexChange", 0);
		$AllowSorting	= getYNExpOfNode($tp, $tp,"Information/SIDE_WIN/AllowSorting", 0);
		$AllowIOFiles	= getYNExpOfNode($tp, $tp,"Information/SIDE_WIN/AllowIOFiles", 0);
		$RecordCycle	= getYNExpOfNode($tp, $tp,"Information/SIDE_WIN/RecordCycle", 0);
		$AllowEvents	= getYNExpOfNode($tp, $tp,"Information/SIDE_WIN/AllowEvents", 0);
		$AllowKeyOptimization = getYNExpOfNode($tp, $tp,"Information/SIDE_WIN/AllowIndexOptimization", 0);
		$AllowLocationInQuery = getYNExpOfNode($tp, $tp,"Information/SIDE_WIN/AllowLocationInQuery", 0);
		$AllowPrintingData	= getYNExpOfNode($tp, $tp,"Information/SIDE_WIN/AllowPrintingData", 0);

		$OpenTaskWindow		= getYNExpOfNode($tp, $tp,"Information/WIN/OpenTaskWindow", 0);
		$CloseTaskWindow	= getYNExpOfNode($tp, $tp,"Information/WIN/CloseTaskWindow", 0);
		$ForegroundWindow	= getYNExpOfNode($tp, $tp,"Information/WIN/ForegroundWindow", 0);
		$FlipFld			= getAttributeOfNode($tp,"Information/WIN/FlipFld", "val", 0);
		$RefreshTaskWindow	= getAttributeOfNode($tp,"Information/WIN/RefreshTaskWindow", "ReturnValue", 0);

		$SelectionTable = getAttributeOfNode($tp,"Information/TaskProperties/SelectionTable", "val", 0);
		$ConfirmUpdate	= getAttributeOfNode($tp,"Information/TaskProperties/ConfirmUpdate", "CNFU", 0);
		$ConfirmCancel	= getAttributeOfNode($tp,"Information/TaskProperties/ConfirmCancel", "val", 0);

		$ErrorStrategy = getAttributeOfNode($tp,"Information/TaskProperties/ErrorStrategy", "val", 0);
		$LockingStrategy = getAttributeOfNode($tp,"Information/TaskProperties/LockingStrategy", "val", 0);
		$CacheStrategy = getAttributeOfNode($tp,"Information/TaskProperties/CacheStrategy", "val", 0);

		$ForceRecordSuffix = getAttributeOfNode($tp,"Information/TaskProperties/ForceRecordSuffix", "val", 0);
		$TransactionMode = getAttributeOfNode($tp,"Information/TaskProperties/TransactionMode", "val", 0);
		$TransactionBegin = getAttributeOfNode($tp,"Information/TaskProperties/TransactionBegin", "val", 0);
		$PreloadView = getAttributeOfNode($tp,"Information/TaskProperties/PreloadView", "val", 0);
		$AllowEmptyDataview = getAttributeOfNode($tp,"Information/TaskProperties/AllowEmptyDataview", "val", 0);
		$KeepCreatedContext = getAttributeOfNode($tp,"Information/TaskProperties/KeepCreatedContext", "val", 0);

		if( $mainFileIdxExp ne '' ){
#			$mainFileIdxExp = expressionStringVar($tp, $mainFileIdxExp,0);
			$mainFileIdxExp = "Expr: " . expressionStringVar($tp, $mainFileIdxExp,0);
		}

#		print STDOUT "Type: $taskType\tMain: $mainFileNbr\tIndex: $mainFileIdxNbr \n" if $HierLevel>1;
		if( $mainFileNbr ne '' ){
			$mainFileNbrL1 = $mainFileNbr - 1;
			($mainFileName, $DataFolder,$DataSource,$DsPhysName) = dataSourceName($mainFileNbr);
			if( $mainFileIdxNbr gt 0 ){
				$mainFileIdxNbrL1 = $mainFileIdxNbr - 1;
				$mainFileIdxDesc = getAttributeOfNode($ds_data, "//Application/DataSourceRepository/DataObjects/DataObject[$mainFileNbr]/Indexes/Index[$mainFileIdxNbr]", "name" , 0);
			}
			else {
				$mainFileIdxDesc = '';
			}
		} else {
			$mainFileNbr = '0';#00u01
		}
		#Indexes are located in DataSources.xml at Application/DataSourceRepository/DataObjects/DataObject[x]/Indexes/Index
		$keyInfo = '';

		$taskName = getAttributeOfNode($tp,"Header","Description", 0);
		$taskName =~ s/ /_/g;#replace spaces with underscores so its recognized by C.-for display here only-not in the hierarchy
		$updateDate = getAttributeOfNode($tp,"Header/LastModified","date", 0);
		$updateTime = getAttributeOfNode($tp,"Header/LastModified","time", 0);

		#0611c - add C subroutine end and start. Will cause us to have one extra unmatched close brace - who cares!
		print "}\n\001\n";
#		print STDOUT "-- $taskName \n";
		print "Task Name: $taskName (){ \t//Last Update: $updateDate $updateTime\n";#583
		
		print "-----\n";
		print "                Main File: $mainFileNbr $mainFileName   Key: $mainFileIdxNbr $mainFileIdxDesc$mainFileIdxExp $mainFileIdxMode\n";
		print "                Task Type: $taskType{$TaskType}\n" if $taskType{$TaskType} ne $ini{lc('deftaskFlow')};
		print "             Initial Mode: $initialMode{$InitialMode}\n" if $initialMode{$InitialMode} ne $ini{lc('defInitialTaskMode')};
#			print "          Selection Table: $selectionTask\n" if $selectionTask ne $ini{lc('defselectionTask')};
		print "            Resident Task: $yesno{$Resident}\n" if $isResident ne $ini{lc('defisResident')};
#		print STDOUT "Task Control\n";
		# //Task Control

		print "         Open Task Window: $OpenTaskWindow\n"	if $OpenTaskWindow ne $ini{lc('defopenTaskWindow')};
		print "        Close Task Window: $CloseTaskWindow\n"	if $CloseTaskWindow ne $ini{lc('defcloseTaskWindow')};
		print "        Foreground Window: $ForegroundWindow\n"	if $ForegroundWindow ne $ini{lc('defforegroundWindow')};
		print "      Refresh Task Window: $yesno{$RefreshTaskWindow}\n" if $yesno{$RefreshTaskWindow} ne $ini{lc('defrefreshWindow')};

		print "      Flip Field on Input: $yesno{$FlipFld}\n"	if $yesno{$FlipFld} ne $ini{lc('defflip')};
		print "        Cycle Record Main: $RecordCycle\n" if $RecordCycle ne $ini{lc('defallowCycleRecordMain')};
		print "           Confirm Update: $yesno{$ConfirmUpdate}\n" if $yesno{$ConfirmUpdate} ne $ini{lc('defconfirmUpdate')};
#			print "             Form Records: 0\n" if $formRecords ne $ini{lc('def0')};

		print "               Locate Exp: $LocateExp\n" if $LocateExp ne $ini{lc('deflocateExp')};
		print "             Locate Order: $LocateDir\n" if $LocateDir ne $ini{lc('deflocateDir')};

		print "                Range Exp: $RangeExp\n" if $RangeExp ne $ini{lc('defrangeExp')};
#			print "     Range/Locate Comment: $rangeComment\n" if $rangeComment ne "";
		print "              Range Order: $RangeDir\n" if $RangeDir ne $ini{lc('defrangeDir')};
		print "                 End Task: $EndTaskCondition\n" if $EndTaskCondition ne $ini{lc('deftaskEndTaskCondition')};
#		print "                End Check: $beforeafter{$EvaluateEndCondition}\n" if $beforeafter{$EvaluateEndCondition} ne $ini{lc('deftaskEndCheck')};
		print "                End Check: $evalEnd{$EvaluateEndCondition}\n" if $EndTaskCondition ne $ini{lc('deftaskEndTaskCondition')};# End Check is only relevant when End Task Condition is not No.
		print "      Force Record Suffix: $yesno{$ForceRecordSuffix}\n" if $yesno{$ForceRecordSuffix} ne $ini{lc('defForceRecordSuffix')};
		print "      Force Record Delete: $yesno{$ForceRecordDelete}\n" if $taskForceRecordDelete ne $ini{lc('deftaskForceRecordDelete')};

		print "         Transaction Mode: $tmode{$TransactionMode}\n" if $tmode{$TransactionMode} ne $ini{lc('def_tmode')};
		print "        Transaction Begin: $tbegin{$TransactionBegin}\n" if $tbegin{$TransactionBegin} ne $ini{lc('def_tbegin')};

		
#		print "         Locking Strategy: $lstrg{$LockingStrategy}\n" if $lstrg{$LockingStrategy} ne $ini{lc('deflstrg')};
		print "         Locking Strategy: $LockingStrategy\n" if $LockingStrategy ne $ini{lc('deflstrg')};#00u01 - does locking strategy have meaning in UniPaaS?
		print "           Cache Strategy: $cstrat{$CacheStrategy}\n" if $cstrat{$CacheStrategy} ne $ini{lc('defscache')};
#		print "  On Failed Record Access: $sfail{$ErrorStrategy}\n" if $sfail{$ErrorStrategy} ne $ini{lc('defsfail')};
		print "  On Failed Record Access: $ErrorStrategy\n" if $ErrorStrategy ne $ini{lc('defsfail')};

		print "            Allow Options: $AllowOptions\n"    if $AllowOptions   ne $ini{lc('defallowOptions')}; #577
		print "             Allow Modify: $AllowModify\n"     if $AllowModify    ne $ini{lc('defAllowModify')};
		print "             Allow Create: $AllowCreate\n"     if $AllowCreate    ne $ini{lc('defAllowCreate')};
		print "             Allow Delete: $AllowDelete\n" 	  if $AllowDelete    ne $ini{lc('defAllowDelete')};
		print "              Allow Query: $AllowQuery\n" 	  if $AllowQuery     ne $ini{lc('defAllowQuery')};
		print "             Allow Locate: $AllowLocate\n" 	  if $AllowLocate    ne $ini{lc('defAllowLocate')};
		print "              Allow Range: $AllowRange\n"      if $AllowRange     ne $ini{lc('defAllowRange')};
		print "         Allow Key Change: $AllowKeyChange\n"  if $AllowKeyChange ne $ini{lc('defAllowKeyChange')};
		print "            Allow Sorting: $AllowSorting\n"    if $AllowSorting   ne $ini{lc('defAllowSorting')};
		print "          Allow I/O Files: $AllowIOFiles\n"    if $AllowIOFiles   ne $ini{lc('defAllowIOFiles')};
		print "              Allow Abort: $AllowAbort\n"      if $AllowAbort     ne $ini{lc('defAllowAbort')};
		print "   Allow Key Optimization: $AllowKeyOptimization\n"     if $AllowKeyOptimization    ne $ini{lc('defAllowKeyOpt')};
		print "    Allow Locate in Query: $AllowLocateInQuery\n" if $AllowLocateInQuery ne $ini{lc('defAllowLocateInQuery')};
		print "            Allow Reports: $AllowReports\n" if $AllowReports ne $ini{lc('defAllowReports')};

		if ($HierLevel eq '1'){
			print "              Query Right: $queryRight\n" if $queryRight ne $ini{lc('defQueryRight')};
			print "             Modify Right: $modifyRight\n" if $modifyRight ne $ini{lc('defModifyRight')};
			print "           Deletion Right: $deletionRight\n" if $deletionRight ne $ini{lc('defDeleteRight')};
			print "          Execution Right: $executionRight\n" if $executionRight ne $ini{lc('defExecuteRight')};
#			if( $progRetValExp ne '' ){#0940-10b3
#				print "          Return Expression: $exp[$p][$t][$progRetValExp ]\n"; #0940-10b3
#			}
		}
		readTaskHierarchy($tp) if $HierLevel == 1;
		#pick up form and event defs before going forward as we need them before processing Task Logic
		$isMainProgram = $tp->getAttribute ("MainProgram") eq 'Y';
		$evntEntryCount = 0;
		#pick up event defs
		foreach $evntEntry ($tp->findnodes("EVNT")){#note the event names
			$evntId = $evntEntry->getAttribute( "id");
#			print STDOUT "evntID: $evntId \n";
			$eName = $evntEntry->getAttribute( "DESC");
			$event_forceExit =  $eForceExit{$evntEntry->getAttribute( "FORCE_EXIT")};
			$eKeyCombo = getAttributeOfNode($evntEntry,"Event/KeyCombinationID", "val", 0);
			if( $eKeyCombo ne ''){
				$eKeyCombo = $eKeyCombo . ' ' . $key_from_col4{$eKeyCombo};
			}
			$eType = $eTypeStr{getAttributeOfNode($evntEntry,"Event/EventType", "val", 0)};

			$evntName[$HierLevel][$evntId] = $eName;
			$evntKey[$HierLevel][$evntId] = $eKeyCombo;
			$evntType[$HierLevel][$evntId] = $eType;

			if ($isMainProgram ){
				$evntName["32768"][$evntId] = $eName;
				$evntKey["32768"][$evntId] = $eKeyCombo;
				$evntType["32768"][$evntId] = $eType;
			}

			$evntEntryCount++;
			if( $evntEntryCount eq '1'){
				print "\n// Events:\n";
				print "// ## Description            Trigger Type      Trigger      Parameters Force Exit     Public Name    Expose\n";
				print "//--------------------------------------------------------------------------------------------------------------------------------\n";
			}
			$~ = 'EVENT_DETAIL';
			write;
		}
#		if( $isMainProgram ){
#			for ( $i=0; $i<=11; $i++){
#				print STDOUT "3:" . $evntName["32768"][$i]. "\n";
#				print STDOUT "L:" . $evntName[$HierLevel][$i]. "\n";
#			}
#		}
		#pick up form defs 
		foreach $formEntry ($tp->findnodes("TaskForms/FormEntry")){#note the form names
			$formId = $formEntry->getAttribute( "id");
#			print STDOUT "formId: $formId \n";
			$formName = getAttributeOfNode($formEntry,"PropertyList/FormName", "valUnicode", 0);
			if ($formName eq '' ){
				$formName = $taskName;
			}
			$form[$formId]->{name} = $formName;
#			print "\n\tForm: $formName id:$formId\n";
		}
		
		printComment($Comment,'Y');
#		print STDOUT $tp->nodeName . "--" . $tp->nodeType. "\n" if $tp->nodeType ne '3' ;
#		for each Task node
		foreach $taskchild ($tp->childNodes){# Under Task: Header, Resource,Information,TaskLogic,TaskForms,Expressions,EVNT. Task
#			print STDOUT $taskchild->nodeName .  "--" . $taskchild->nodeType . "\n" if $taskchild->nodeName ne '#text';
			$taskName = $taskchild->getAttribute('Description') if($taskchild->nodeName eq 'Header');

			$taskChildNodeName = $taskchild->nodeName;
			if( $taskChildNodeName eq 'Information'){
			}
			elsif( $taskChildNodeName eq 'Task'){
#				print STDOUT "task begin\n";
				getPrgResources10($taskchild, $HierLevel+1); #var pointing to Task node
				$HierLevelT = $HierLevel;
#				print STDOUT "task end\n";
			}
			elsif( $taskChildNodeName eq 'SQL_FORM'){
				processSQL_FORM($tp, $taskchild); 
			}
			elsif( $taskChildNodeName eq 'TaskLogic'){ #TaskLogic/LogicLines/Select
				processTaskLogic($tp, $taskchild, 0, $mainFileNbr); #var pointing to TaskLogic node
			}
			elsif( $taskChildNodeName eq 'Resource'){
				processTaskResources($tp, $taskchild,0); #var pointing to Resources node  -do this earlier on.
			}
			elsif( $taskChildNodeName eq 'EVNT'){#do it all at beginning of task
			}
			elsif( $taskChildNodeName eq 'VarRangeInfo'){# don't know what it does - see prog 3 , but don't think its significant
				$VarRangeMode = $taskchild->getAttribute("Mode");
				$VarRangeVeeIsn = $taskchild->getAttribute("VarRangeVeeIsn");
#				print STDOUT "Unhandled node: NodeName = $taskChildNodeName in Prog: $PrgId\n";
			}
			elsif( $taskChildNodeName eq 'DISPLAY'){# don't know what it does - see prog 5
#				print STDOUT "Unhandled node: NodeName = $taskChildNodeName in Prog: $PrgId\n";
			}
			elsif( $taskChildNodeName eq 'ItemIsn'){# don't know what it does, but don't think its significant
				$ItemIsnVal = $taskchild->getAttribute("val");
#				print STDOUT "Unhandled node: NodeName = $taskChildNodeName in Prog: $PrgId\n";
			}
			elsif( $taskChildNodeName eq 'INT_RECOMP_INFO'){# don't know what it does, but don't think its significant
#				print STDOUT "Unhandled node: NodeName = $taskChildNodeName in Prog: $PrgId\n";
			}
			elsif( $taskChildNodeName eq 'Expressions'){#used elsewhere
			}
			elsif( $taskChildNodeName eq 'Header'){#used elsewhere
			}
			elsif( $taskChildNodeName eq 'TaskForms'){
				processTaskForm($tp, $taskchild);
			}
			elsif( $taskChildNodeName eq 'FLD_RNG'){#usually in a combo box, see programs 24, 74, 2010
				$frMin = getAttributeOfNode( $taskchild, "Min", "val", 0);
				$frMin = expressionStringVar($taskp, $frMin, 0) if $frMin ne '';
				$frMax = getAttributeOfNode( $taskchild, "Max", "val", 0);
				$frMax = expressionStringVar($taskp, $frMax, 0) if $frMax ne '';
				$frField = getAttributeOfNode( $taskchild, "_Column", "obj", 0);
#				$frField = varName();  #Need to translate the field name
				print "Field Range: field $frField min $frMin max $frMax \n";
			}
			elsif( $taskChildNodeName eq 'SQL_WHERE_U'){
				# program 20
				#This is the SQL Where tab of Range Locate for the task
				#Header/SqlWhereExist = Y probably indicates this section exists
				$swuCode = getAttributeOfNode( $taskchild, "TOKEN/CODE", "val", 0);
				$swuFlag = getAttributeOfNode( $taskchild, "TOKEN/SqlWhereFlags", "val", 0);
				$swuParent = getAttributeOfNode( $taskchild, "TOKEN/Parent", "val", 0);
				$swuVarIsn = getAttributeOfNode( $taskchild, "TOKEN/VAR_ISN", "val", 0);
				print "SQL Where Code:$swuCode Flags:$swuFlag Parent:$swuParent, Var Isn:$swuVarIsn\n";
#				print STDOUT "Unhandled node: NodeName = $taskChildNodeName in Prog: $PrgId\n";
			}
			elsif( $taskChildNodeName eq 'ReturnValueExpression'){#don't know what it does - see program 32  not significant.
#				print STDOUT "Unhandled node: NodeName = $taskChildNodeName in Prog: $PrgId\n";
			}
			elsif( $taskChildNodeName eq 'MAGIC_SQL'){#don't know what it does - see program 541
#				print STDOUT "Unhandled node: NodeName = $taskChildNodeName in Prog: $PrgId\n";
			}
			elsif( $taskChildNodeName eq '#text'){
			}
			else {
				print STDOUT "Unhandled node: NodeName = $taskChildNodeName \n";
			}
		}
	}
	sub writeProgram #pass=2
	{
		$p++;
		$t=0;
		$hier='1';
		$mainFile = 'None';

		$queryRight   = '_??_';
		$modifyRight  = '_??_';
		$deleteRight  = '_??_';
		$executeRight = '_??_';

		# replace characters prohibited in file names with hyphens so epsilon can write a file name
		# replace spaces so epsilon is not confused when creating buffer names
		$progAsFname = $progName;#600
		# I tried to retain spaces in filenames  but wasn't successful.
		# even if successful, wouldn't Epsilon get confused with buffer names?
		$progAsFname =~ tr/\\\/?*:<>% /-/;
	#   $progAsFname =~ tr/\\\/?*:<>%/-/; #0608 don't replace the spaces as I had been doing.
		$prgNumber = sprintf("%04d",$PrgId);

		if( $ini{lc('generateHtml')} eq 'True' ){$FileExt = 'html'}#584
		else {$FileExt = 'txt'} #610 FileExt was ezr, but set to txt so Google will index it.
		$outfile = "z$prgNumber-$progAsFname." . $FileExt;

		open( OUT, "> $outfile" );
		select OUT;
		$startSecs = time;

		if ($os eq 'Windows_NT'){
			$date = `date /t`;
			$time = `time /t`;
			chomp( $date );
			chomp( $time );
			$date .= ' ' . $time;
		}
		else{
			$date = 'n/a';
		}
		if( $ini{lc('generateHtml')} eq 'True' ){ #584
			print "<html><title></title><body><pre>\n";
		}
		print "//mgFargo: Magic Source Translation - Version $mgMajorVers.$mgMinorVers $versionDate by Ira Gershenhorn w\\Perl $] \n";  #0614
		print "#define mgFargo 1\n\n";  #0614
		print " Program: $progName\t\tFolder:[$progFolder]\t\t$date";
		print "\t\tPublic:[$progPublic]" if $progPublic ne '';
		print "\n\n" ;

		$indentLevel = 1;
		$indentLevelPrev = 1;
		@indentExp =();

		initTaskVarsPrescan();

		$t=1;
		$hier='1';
		$eventn = 0;
		
		getPrgResources10($pt[0], 1); 
		$elapsed = time - $startSecs;
		print "\n// Elapsed Time for $progName: $elapsed seconds\n\n";
#		print STDOUT "\n// Elapsed Time for $progName: $elapsed seconds\n\n";
#		undef $exp[$p];
		close OUT;
	}
	#getArgsAndFlow is a rearranger.  Magic outputs important info about a function on the
	# last line of the function, eg ARGS for raise event and all Calls.
	# This function moves that info up.
	# its safe to move everything after the }, as in ARG=(,SKIP=N|Y),
	#
	# RAISE_EVENT is different.  Its first line is always EVENT_TRIGGER followed by optional ARG.
	#  The last ARG will have the FLW string.  If no ARG, then EVENT_TRIGGER has it.
	
	sub usage{
	   pod2usage( { -message => "\n" . $0 . ": ". $error . "\n\n" . $copyrightLine ,
					-exitval => 1  ,  
					-input => $mgFargoIniPath . "mgFargo.pod",
					-verbose => 0  
					 } );
	}
	sub detailedUsage{
	   pod2usage( { -message => $copyrightLine ,
					-exitval => 0  ,  
					-verbose => 1,
					-input => $mgFargoIniPath . "mgFargo.pod",
					-output => \*STDOUT
					 } );
	}
	sub manpage{
	   pod2usage( { -message => $copyrightLine ,
					-exitval => 0  ,  
					-verbose => 2,
					-input => $mgFargoIniPath . "mgFargo.pod",
					-output => \*STDOUT
					 } );
	}
	sub read_mgFargo_ini{
		my $path = $1 if $file =~ /(^.*\/)/;
		my $ini = $path . 'mgFargo10.ini';
		$ini = $mgFargoIniPath . 'mgFargo10.ini';
		print STDOUT "testing for mgFargo10.ini at [$ini]\n";
		if (!(-f $ini )){ print STDOUT "Warning: mgFargo10.ini not found!\n";}
		else {
			my $skipping = 0;

			print STDOUT "opening $ini configuration parameters\n";
			open INI, "< $ini";
			while (<INI>) {

				if (!$skipping && /^(\w+)\s*=\s*([^\s;]+)/)	{
					$ini{lc($1)}=$2;
				}
				elsif ( /^\[(\w+)\]/){
					if ( $ini{lc('enableDefaults')} ne 'True' ){
						last;
					}
					elsif (	!/^\[$ini{lc('defaultsSection')}\]/i){
						$skipping = 1;
					}
				}
			}
			close INI;
		}

	}
	#Typical lines
	# 0         1         2         3
	# 01234567890123456789012345678901234567890
	#  action = key , action, action code, other number, states
	#User Action 1      =           ,  219,    0,0x000000000
	#Close              = Ctrl+F4             ,   13,  103,0x000000000
	sub read_act_eng10{ #587
		my $act_eng_path = $supportFilesPath;
		my $act_eng = $supportFilesPath . 'act_std.eng';
		print STDOUT "testing for act_std.eng at [$act_eng]\n";
		if (!(-f $act_eng )){ print STDOUT "Warning: act_std.eng not found!\n";}
		else {
			print STDOUT "opening $act_eng Actions Definition\n";
			open INI, "< $act_eng";
			while (<INI>) {
				my ($col1,$col2, $col3, $col4, $col5) = /(^[^=]+)=([^,]+),([^,]+),([^,]+),(.+$)/;
				#
				$col1 = trim($col1);
				$col2 = trim($col2);
				$col3 = trim($col3);
				$col4 = trim($col4);
				$col5 = trim($col5);
				$code_from_action{$col1} = $col3;
				$action_from_code{$col3} = $col1;
				$code_from_key{$col2} = $col3;
				$key_from_code{$col3} = $col2;
				$key_from_col4{$col4} = $col2; # use for events
#				if( $col4 == 8 ){
#					print STDOUT "act_eng $col1, $col2, $col3, $col4, $col5 ". $action_from_code{$col3}. " \n";
#				}
			}
			close INI;
		}
	}
	#600
	#Typical line
	# 0         1         2         3
	# 01234567890123456789012345678901234567890
	#Default Table Edit Field,MS Sans Serif,8,0,0
	sub read_fnt_eng{ #600
		my $fnt_eng_path = $supportFilesPath;
		my $fnt_eng = $fnt_eng_path . 'fnt_std.eng';
		my $fnt_index = 0;
		print STDOUT "testing for fnt_std.eng\n";
		if (!(-f $fnt_eng )){ print STDOUT "Warning: fnt_std.eng not found!\n";}
		else {
			print STDOUT "opening $fnt_eng Font Definition\n";
			open INI, "< $fnt_eng";
			while (<INI>) {
				chomp;
				$fnt_index+=1;
				($fnt_use, $fnt_face,$fnt_size,$fnt_number,$fnt_style) = split( /,/ );
				$fnt[$fnt_index]->{use} = $fnt_use;
				$fnt[$fnt_index]->{face} = $fnt_face;
				$fnt[$fnt_index]->{size} = $fnt_size;
				$fnt[$fnt_index]->{number} = $fnt_number;
				$fnt[$fnt_index]->{style} = $fnt_style;
			}
			close INI;
		}
	}

	sub basicUsage()
    {
        print STDERR << "EOF";

    This program does...

    usage: $0 [-isvhfbe]

     -h        : this (HELP) message
     -v        : VERBOSE output
     -i        : path to mgFargo10.INI
     -s        : path to SUPPORT files like act_std.eng
     -f        : path to source FILES (no final slash) ie. source of the xml files.
	 -b		   : BEGIN program
	 -e		   : END program

    example: $0 -i <path to mgFargo.ini> -s <path to Support files>  appExpFile

EOF
        exit;
    }

format SORT_DETAIL =
  @>>  @>>>>>>>> @>>> @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
	$v, $sortSeg[$v]->{'direction'}, $sortSeg[$v]->{'size'}, $sortSeg[$v]->{'field'}
.

#no sequence numbers   #601 add DB tag and reduce indent
format DB_DETAIL =
DB @>> @<<<<<<<<<<<<<<<<<<<<<<< @<<<<< @<<<< @<<<<<<< @<<<<<<< @<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<
   $DataObjectNum, $DataObject, $Access,$Share,$Open, $Cache,"None Defined", $DataFolder,$DataSource,$DsPhysName
.

format VIRTUAL_DETAIL =
	   @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @>>>> @<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<< @<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
		$ColumnName,	'', '', $ColumnDesc, $ColumnAttr, $ColumnPic, '',  $DefaultValue
.

format VIRTUAL_M_DETAIL =
	   @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @>>>> @<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<< @<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
		$ColumnName,	$Model, $models[$Model]->{name},$models[$Model]->{desc},$models[$Model]->{attr}, $models[$Model]->{pic}, $models[$Model]->{range},$models[$Model]->{comment},  $DefaultValue
.

# format VIRTUAL_DETAIL =
# @>>>> @<<<<<<<<<<<<<<<<<<<< @>>> @<<<<<<< @<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
# $v,	$virt[$p][$t][$v]->{desc},	$virt[$p][$t][$v]->{type}, $virt[$p][$t][$v]->{attr}, $virt[$p][$t][$v]->{pic}, $virt[$p][$t][$v]->{range}
#.

format HTML_HEADER =
<HTML>
   <HEAD>
	  <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
	  <META NAME="Author" CONTENT="mgFargo">
	<TITLE>Application Directory</TITLE>
	</HEAD>
	<BODY>
	<H2>Application Program Files</h2>
	<TABLE WIDTH="100%" >
.

#New FORMAT formats which lead off with row colum.	     
format NFORM_DETAIL_L =
| @>> @>> @>> @>> @>> @>>>>>>>>>:                                    @>>>> @<<<<<<< @<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 $row, $col,$rows,$cols,$allowInput,$item,                  $attr,$pic,    $picExp,                $otherCtlCharacteristics
|                                @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
										$it
.

format NFORM_DETAIL_S =
// +-Row+-Col+Rows+Cols+Allow+-------- Name -------+Attr+-- Pic --+--------Pic-Exp--------\n";
| @>> @>> @>> @>> @>> @>>>>>>>>>:@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @>>>> @<<<<<<< @<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 $row, $col,$rows,$cols,$allowInput,$item,   $it,         $attr,$pic,    $picExp,                $otherCtlCharacteristics
.

#600
format NFORM_STATICS =
| @>> @>> @>> @>>     @>>>>>>>>>:@<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<< @>>>> @<<<<<<<<<<<<<<<<<<<<< onReturn: @<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 $row, $col,$rows,$cols,$item,   $it,                   $fldDesc,             $attr, $pic,                            $pb_action_str,      $otherCtlCharacteristics
.
#600
format NFORM_STATICS_L =
| @>> @>> @>> @>>     @>>>>>>>>>:                       @<<<<<<<<<<<<<<<<<<<<< @>>>> @<<<<<<<<<<<<<<<<<<<<< onReturn: @<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 $row, $col,$rows,$cols,$item,                         $fldDesc,             $attr, $pic,                            $pb_action_str,      $otherCtlCharacteristics
|                                @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
								 $it
.
#600
format NFORM_PUSHBUTTON =
| @>> @>> @>> @>>     @>>>>>>>>>:@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @>>>> @<<<<<<<<<<<<<<<<<<<<< onReturn: @<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 $row, $col,$rows,$cols,$item,   $it,                                        $attr, $pic,                            $pb_action_str,      $otherCtlCharacteristics
.
#600
format NFORM_CheckBox =
| @>> @>> @>> @>> @>> @>>>>>>>>>:@<<<<<<<<<<<<<<<<< Label:@<<<<<<<<<<<<<<< onReturn: @<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 $row, $col,$rows,$cols,$allowInput,$item,       $it,  $itm_txt,             $pb_action_str.      $otherCtlCharacteristics
.

#Original FORMAT formats
format FORM_DETAIL_L =
| @<<<<<:                        @<<<< @<<<<<<< @<<<<<<<<<<<<<<<<<<<<<< @>>> @>>> @>>> @<<< @>>>> @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 $item,                       $attr,$pic,    $picExp,               $row, $col,$rows,$cols,$allowInput,$otherCtlCharacteristics
|      @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
	  $it
.

format FORM_DETAIL_S =
//     +-------- Name -------+Attr+-- Pic --+--------Pic-Exp--------+-Row+-Col+Rows+Cols+Allow+\n";
| @<<<<<: @<<<<<<<<<<<<<<<<<<<<< @<<<< @<<<<<<< @<<<<<<<<<<<<<<<<<<<<<< @>>> @>>> @>>> @<<<  @>>>> @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 $item,   $it  ,              $attr,$pic,    $picExp,                $row,$col,$rows,$cols,$allowInput,$otherCtlCharacteristics
.

#587
format FORM_STATICS =
| @<<<<<<<<<: @<<<<<<<<<<<<<<<<<<<<< at:  @>>>, @>>> dimension: @>>>, @>>>> returnaction: @>>> @<<<<<<<<<<<<<<<<<<
 $item,      $pic,                  $row,$col,             $rows,$cols,$pb_action, $pb_action_str
.
#600
format FORM_CheckBox =
| @<<<<<<<<<: @<<<<<<<<<<<<<<<<< Label: @<<<<<<<<<<<<<<< at:  @>>>, @>>> dimension: @>>>, @>>>> returnaction: @>>> @<<<<<<<<<<<<<<<<<<
 $item,       $it,                      $itm_txt,             $row,$col,             $rows,$cols,$pb_action, $pb_action_str
.


#0573,#574
format EVENT_DETAIL =
@>>>> @<<<<<<<<<<<<<<<<<<<<<<  @<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<  @<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<< 
$evntId, $eName,				$eType,       $eKeyCombo,        $event_parameters,  $event_forceExit
.

# Under Task: Header, Resource,Information,TaskLogic,TaskForms,Expressions,EVNT
#Task
# Header  
# Resource
#  DB+
#  Columns
#    Column+
# Information
# TaskLogic
#   LogicUnit+
#     LogicLines
#       LogicLine+
# TaskForms
# Expressions 
#   Expression+
# Task+
# EVNT+ 
#  
# LogicUnit
#	Level=Record,Task,Handler
#	Type =Suffix, Prefix, Main,User
#   
#   Scope=Subtask
#	Remark/Text(val)
#   Event
#     EventType System,User
#   LogicLines
#     LogicLine
#       Select
#         Type.val =Real, Virtual
#       Select.Column.val
#      in DataSources.xml:
#      //Application/DataSourceRepository/DataObjects/DataObject[]/Columns/Column[].name
#  
#  
# EVNT (follows Expressions).DESC
#   EventType System,None
#   KeyCombinationID
#   PublicObject for the Expose property that's never checked.
#  
#  
#  
# TaskForms
#  FormEntry
#    PropertyList
#      FormName valUnicode
#
#
#
#
#  Reference syntax:
#  {32768, 1 } = first field in Main task
#  {0, 1 } = first field in current program
#
# Known Issues
# 
# 2020	Prg_2020.xml	Browse - Workflow Filter Types	Martin	___
# currentDb?
# currendDb , dn:, cv: 
#
#
# What is this?  in prog 1262 I90 DD Letters (Intro Docs)
# Wide character in print at D:\dev\mgFargo\mgFargo-101-00u.pl line 1316.
# This is from some spanish or portuguese text beginning with Credit Control.